zoukankan      html  css  js  c++  java
  • 正则表达式小技巧(不断更新中...)

     一、多个结果匹配

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

    方法一:

    使用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 = @"((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,((w+?)[,:;]?s?)算是一个分组,索引是2,(w+?)是一个分组,索引是3.所以这个会输出三个分组。

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

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

     输出如下结果:

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

    2、非捕获组

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

    (?:subexpression)

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

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

    string pattern = @"((?: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+)sk<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]+$也是一样的结果。

  • 相关阅读:
    什么是级联
    @GeneratedValue
    Spring Data JPA中CrudRepository与JpaRepository的不同
    Spring Data JPA的方法命名规则
    C/S架构的渗透测试-请求加解密及测试
    各类Fuzz字典
    Nessus8.11破解
    xss实验1-20writeup
    IIS短文件名漏洞
    Linux挂载exfat文件系统的U盘
  • 原文地址:https://www.cnblogs.com/yunfeifei/p/4129099.html
Copyright © 2011-2022 走看看