• 正则表达式分组相关的知识


    一、组的分类
    正则中的组有捕获组和非捕获组,而捕获组又分为普通的捕获组和命名捕获组,分别为
    捕获组:(exp)
    命名捕获组:(? <name> exp)
    非捕获组:(?:exp)

    二、组的作用
    1、捕获组的作用

    捕获组的作用是将正则表达式exp匹配到的内容保存到组里,供以后使用

    比如这样一个字符串:
    <a href="http://bbs.csdn.net" title="床上等你"> CSDN </a>
    我想得到网址,而它符合的规则是在 <a...> 标签内,那就可以这样做
    C# code
    string test = "<a href=\"http://bbs.csdn.net\" title=\"床上等你\">CSDN</a>"; Match m = Regex.Match(test, @"<a\s*href=""([^""]*)""[^>]*>", RegexOptions.IgnoreCase); if (m.Success) MessageBox.Show(m.Groups[1].Value);

    上面的正则表达式匹配到了 <a href="http://bbs.csdn.net" title="床上等你"> ,而我们想得到网址,表达式其它部分只是为了保证取到的网址是在 <a...> 标签内的,所以这里用到的捕获组,把匹配到的网址保存到捕获组里,然后用m.Groups[1].Value得到这个捕获组所匹配到的内容
    m.Groups[1].Value是一种对捕获的引用方式,还有另外一种引用方式m.Result("$1"),效果是一样的

    普通捕获组是用1,2,3...这样的自然数对捕获组进行引用的
    而命名捕获组可以不用去数捕获组的序号,直接通过捕获组的命称对它进行引用

    C# code
    string test = "<a href=\"http://bbs.csdn.net\" title=\"床上等你\">CSDN</a>"; Match m = Regex.Match(test, @"<a\s*href=""(?<url>[^""]*)""[^>]*>", RegexOptions.IgnoreCase); if (m.Success) MessageBox.Show(m.Groups["url"].Value);


    至于捕获组的分组命名及序号排序规则,在后面说明

    2、非捕获组的作用
    非捕获组的作用有两个,第一个比较常用,第二个了解一下即可

    (1)、节省系统资源,提高效率
    在使用“ ¦”表示“或”的关系时,稍微复杂的情况,需要用()来限制“ ¦”的作用范围,否则即表示“ ¦”的左右两侧整体为“或”的关系,这是题外话,这里不详细说明了,还有用{num}来表达式匹配次数时,有时前面也要用到()限制作用范围
    而使用()来限制作用范围的同时,默认情况下会把匹配到的结果保存到一个捕获组里,而大多数时候,我们是不需要保存这部分内容的,这就带来一定的副作用,浪费了系统资源,降低了效率
    非捕获组的一个作用就是用来消除这种副作用的,(?:exp)用来匹配exp所表示的规则,但不将匹配结果保存到捕获组里

    比如匹配HH:mm:ss这样的时间
    C# code
    MessageBox.Show(Regex.IsMatch("18:23:55", "^(?:[01][0-9]|2[0-3])(?::[0-5][0-9]){2}$").ToString());

    (?:[01][0-9] ¦2[0-3])验证小时部分是否符合规则,但不会将匹配结果保存到捕获组里
    (?::[0-5][0-9]){2}验证了分秒部分,但不会将匹配结果保存到捕获组里

    (2)、在使用Regex.Split方法时,起到与RegexOptions .ExplicitCapture参数相同的作用,这个用得不多,了解一下就行了

    三、捕获组分组命名及序号排序
    普通捕获组是按“(”从左到右出现的先后顺序以自然数1,2,3...进行命名的
    命名捕获组就是以(? <name> exp)中的name进行命名的

    但是要注意一点,在表达式匹配成功的前提下,$0在任何情况下都表示整个表达式所匹配到的内容,m.Groups[0].Value表示整个表达式匹配到的内容,可以简写为m.Value

    另外就是命名捕获组除了可以用name对它进行引用外,还可以通过序号对它引用,它的命名规则为:先对普通捕获组从左到右进行序号命名,然后再从开头,从左到右对命名捕获组进行序号命名,举例如下

    <a\s*href="(? <url> [^"]*)"\s*title="([^"]*)"[^> ]*> (? <text> [\s\S]*?) </a>
    2 url 1 3 text

    C# code
    string test = "<a href=\"http://bbs.csdn.net\" title=\"床上等你\">CSDN</a>"; Match m = Regex.Match(test, @"<a\s*href=""(?<url>[^""]*)""\s*title=""([^""]*)""[^>]*>(?<text>[\s\S]*?)</a>", RegexOptions.IgnoreCase); if (m.Success) { richTextBox1.Text += m.Groups[0].Value + "\n"; //<a href="http://bbs.csdn.net" title="床上等你">CSDN</a> richTextBox1.Text += m.Groups[1].Value + "\n"; //床上等你 richTextBox1.Text += m.Groups[2].Value + "\n"; //http://bbs.csdn.net richTextBox1.Text += m.Groups["url"].Value + "\n"; //http://bbs.csdn.net richTextBox1.Text += m.Groups[3].Value + "\n"; //CSDN richTextBox1.Text += m.Groups["text"].Value + "\n"; //CSDN }


    四、组的另一种引用方式
    除了上面 m.Groups[1].Value 和 m.Result("$1") 这两种对结果集进行处理时的引用方式外,还有在替换时的一种引用方式,举例如下

    只保留网址和链接文字,去掉 <a...> 标签中其它无用信息
    C# code
    string test = "<a href=\"http://bbs.csdn.net\" title=\"床上等你\">CSDN</a>"; string result = Regex.Replace(test, @"<a\s*href=""([^""]*)""\s*title=""([^""]*)""[^>]*>(?<text>[\s\S]*?)</a>", @"<a href=""$1"">${text}</a>", RegexOptions.IgnoreCase); MessageBox.Show(result);


    普通捕获组就是用$number来引用,而命名捕获是用${name}来引用
  • 相关阅读:
    Script:Generate A DDL Script For A Table
    如何在windows vista/2008/7中 安装Oracle OMS 即Grid Control
    Sqlserver2005迁移至Oracle系列之五:角色、用户、及权限
    Mysql:命令选项、配置选项、(全局、会话)系统变量、状态变量:SQL模式
    Mysql:命令选项、配置选项、(全局、会话)系统变量、状态变量:如何使用系统变量?
    Mysql:临时表、表变量
    Sqlserver2005迁移至Oracle系列之四:在Oracle中创建位或运算函数bitor
    flex 图片旋转
    基于模板和XML在BS结构应用中生成word文件
    操作图片文件写入word
  • 原文地址:https://www.cnblogs.com/xuzhiwei/p/1818595.html
Copyright © 2020-2023  润新知