正则表达式小技巧(不断更新中...)

 一、多个结果匹配

  我们使用正则表达式大多是在做输入验证的时候,也就是仅仅匹配一个符合条件的结果,但是如果我们解析一些特殊格式的文本,需要多个匹配结果,那么该如何获得多个匹配结果呢?下面来介绍两种方法:

方法一:

使用Matches方法,获得MatchCollection结果,遍历MatchCollection取得匹配的结果。

string equ = @"\w*@.*";
Regex rgx = new Regex(@"\d+?\d+_?\d*", RegexOptions.IgnoreCase);
foreach (Match m in rgx.Matches(equ)) // 使用 Matches 方法
{
    Console.WriteLine(m.Value);
}

方法二:

使用NextMatch方法,当匹配成功时,继续向下匹配。

Match m = rgx.Match(equ); // 也可以使用 Match 方法匹配第一个
while (m.Success)
{
    Console.WriteLine(m.Value);

    m = m.NextMatch(); // 使用 NextMatch 获得下一个
}

 

 二、RegexOptions 枚举

   RegexOptions枚举提供一些正则的匹配选项,如忽略大小写、多行模式、单号模式等,下面是MSDN的说明:

一个 RegexOptions 值,它可作为参数提供给 Regex 类的下列成员:

Regex.Regex(String, RegexOptions) 类构造函数。

Regex.Split(String, String, RegexOptions) 方法。

Regex.IsMatch(String, String, RegexOptions) 方法。

Regex.Match(String, String, RegexOptions) 方法。

Regex.Matches(String, String, RegexOptions) 方法。

Regex.Replace(String, String, String, RegexOptions) 和 Regex.Replace(String, String, MatchEvaluator, RegexOptions) 方法。

 

 三、正则表达式--分组

 1、使用Group和Capture

string pattern = @"(\b(\w+?)[,:;]?\s?)+[?.!]";
         string input = "This is one sentence. This is a second sentence.";

         Match match = Regex.Match(input, pattern);
         Console.WriteLine("Match: " + match.Value);
         int groupCtr = 0;
         foreach (Group group in match.Groups)
         {
            groupCtr++;
            Console.WriteLine(String.Format("   Group {0}: '{1}'", groupCtr, group.Value));
            int captureCtr = 0;
            foreach (Capture capture in group.Captures)
            {
               captureCtr++;
               Console.WriteLine(String.Format("      Capture {0}: '{1}'", captureCtr, capture.Value));
            }
         }

Group及正则表达式中的分组,在这个例子中,整个正则表达式算一个分组,索引是1,(\b(\w+?)[,:;]?\s?)算是一个分组,索引是2,(\w+?)是一个分组,索引是3.所以这个会输出三个分组。

在此正则表达式模式中,子模式 (\w+?) 旨在匹配一个句子中的多个单词。 但是,Group 对象的值只表示 (\w+?) 捕获的最后一个匹配,而 Captures 属性返回表示所有捕获对象的 CaptureCollection。 如输出所示,第二个捕获组的 CaptureCollection 包含四个对象。 其中的最后一项对应于 Group 对象。

注意:正则中的分组索引是从1开始的。

 输出如下结果:

可以看到Group3的匹配结果没有空格。

 

2、非捕获组

以下分组构造不会捕获由子表达式匹配的子字符串:

(?:subexpression)

其中子表达式为任何有效正则表达式模式。 当一个限定符应用到一个组,但组捕获的子字符串并非所需时,通常会使用非捕获组构造。

 修改一中的正则表达式为:

string pattern = @"(\b(?:\w+?)[,:;]?\s?)+[?.!]";

会发现输出结果只有两个分组,而不会捕获(?:\w+?)这个分组。

 

 3、分组命名

以下分组构造捕获匹配的子表达式,并允许你按名称或编号访问它:

(?<name>subexpression)
或:
(?'name' subexpression)

其中名称是有效的组名称,而子表达式是任何有效的正则表达式模式。 名称不得包含任何标点符号字符,并且不能以数字开头。

下面是MSDN上面的一个例子,找到重复单词的位置,并输出在哪个单词之后。

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)";
      string input = "He said that that was the the correct answer.";
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
         Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.", 
                           match.Groups["duplicateWord"].Value, match.Groups["duplicateWord"].Index, 
                           match.Groups["nextWord"].Value);

   }
}
//       The example displays the following output:
//       A duplicate 'that' at position 8 is followed by 'was'.
//       A duplicate 'the' at position 22 is followed by 'correct'.

可用以下方式访问已命名的捕获组:
  1、通过使用正则表达式中的命名的反向引用构造。 使用语法 \k<名称> 在同一正则表达式中引用匹配的子表达式,其中名称是捕获子表达式的名称。
  2、通过使用正则表达式中的反向引用构造。 使用语法 \数字 在同一正则表达式中引用匹配的子表达式,其中数字是捕获的表达式的初始数字。 已命名的匹配子表达式在匹配子表达式后从左到右连续编号。
  3、通过使用 Regex.Replace 或 Match.Result 方法调用中的${名称}替换序列,其中名称为捕获的子表达式的名称。
  4、通过使用 Regex.Replace 或 Match.Result 方法调用中的$编号替换序列,其中编号为捕获的子表达式的序号。

 

 四、正则表达式匹配汉字

使用[\u4e00-\u9fa5]可以匹配任意汉字。

这里是几个主要非英文语系字符范围

2E80~33FFh:中日韩符号区。收容康熙字典部首、中日韩辅助部首、注音符号、日本假名、韩文音符,中日韩的符号、标点、带圈或带括符文数字、月份,以及日本的假名组合、单位、年号、月份、日期、时间等。

3400~4DFFh:中日韩认同表意文字扩充A区,总计收容6,582个中日韩汉字。

4E00~9FFFh:中日韩认同表意文字区,总计收容20,902个中日韩汉字。

A000~A4FFh:彝族文字区,收容中国南方彝族文字和字根。

AC00~D7FFh:韩文拼音组合字区,收容以韩文音符拼成的文字。

F900~FAFFh:中日韩兼容表意文字区,总计收容302个中日韩汉字。

FB00~FFFDh:文字表现形式区,收容组合拉丁文字、希伯来文、阿拉伯文、中日韩直式标点、小符号、半角符号、全角符号等。

比如需要匹配所有中日韩非符号字符,那么正则表达式应该是^[\u3400-\u9FFF]+$ 
理论上没错, 可是我到msn.co.ko随便复制了个韩文下来, 发现根本不对, 诡异 
再到msn.co.jp复制了个'お', 也不得行..

然后把范围扩大到^[\u2E80-\u9FFF]+$, 这样倒是都通过了, 这个应该就是匹配中日韩文字的正则表达式了, 包括我們臺灣省還在盲目使用的繁體中文

而关于中文的正则表达式, 应该是^[\u4E00-\u9FFF]+$, 和论坛里常被人提起的^[\u4E00-\u9FA5]+$很接近

需要注意的是论坛里说的^[\u4E00-\u9FA5]+$这是专门用于匹配简体中文的正则表达式, 实际上繁体字也在里面, 我用测试器测试了下'中華人民共和國', 也通过了, 当然, ^[\u4E00-\u9FFF]+$也是一样的结果。

 

posted @ 2014-11-28 17:45  雲霏霏  阅读(2729)  评论(0编辑  收藏  举报