匹配模式

  • 讲道理的正则表达式对于 *+? 的匹配模式是贪心匹配
    • a*a*b匹配aab时,a*吃掉了两个a,而a*没得a吃
  • 在 *+? 后面加上一个 ? 可以把匹配模式变为惰性匹配
    • a*?a*?b 匹配aab时,a*?一个a都不吃,而a*?被迫吃掉了两个a
  • 在 *+? 后面加上一个+可以把匹配模式变为侵占匹配
    • a*+a无法匹配aaa,因为a*+抢走了所有的a,导致a匹配失败

分组

  • \ 如\1,引用前面的第1个分组
    var match = Regex.Match("abcabc", @"(.+)\1");
    // match.Groups[1] = "abc"
    
    var result = Regex.Replace(" 358 * (126 + 282)", @"(\d+) \* \((\d+) \+ (\d+)\)", "$1 * $2 + $1 * $3");
    // result = "358 * 126 + 358 * 282"
    
  • 对于不想要的分组,开头加上 ?:
    var match = Regex.Match("abcabc", @"(?:.+)\1");
    // Reference to undefined group number 1
    
    注意只要有一对单独的圆括号就存在一个组,顺序为开括号出现的顺序
    var match = Regex.Match("abcdef", @"(?:a(bc)(d(ef)))");
    // match.Groups[1] = bc
    // match.Groups[2] = def
    // match.Groups[3] = ef
    
  • 分组时用 ? 指定名字,即可用 \k 的方式引用
    var match = Regex.Match("abcabc", @"(?<x>.+)\k<x>")
    // match.Groups["x"] = abc 正则替换的引用方式:
    var result = Regex.Replace(" 358 + 126", @"(?<A>\d+) \+ (?<B>\d+)", "${B} + ${A}")
    // result = "126 + 358"
    

断言

  • (?<=x)y 匹配前面匹配 x 的 y
  • x(?=y) 匹配后面匹配 y 的 x
  • (?<!x)y 匹配前面不匹配 x 的 y
  • x(?!y) 匹配后面不匹配 y 的 x
  • ^ 断言当前位置为字符串开头
  • $ 断言当前位置为字符串末尾
  • \b 断言当前位置为单词(包括数字下划线)的边界

C# 特供

  • C# 对于正则的分组行为强于其它语言
    • 组以堆栈的形式存在而非单个元素
    • 对于同组匹配多个的正则,能同时存储被匹配的内容
    • 对于带名称的分组效果相同
    • 除了放入元素还可以取出元素,遵循堆栈的后入先出原则
      Pattern p = Pattern.compile("(.)+")
      Matcher m = p.matcher("abc");
      if (m.matches())
      System.out.println(m.group(1));
      // 输出:c
      
      var groups = Regex.Match("abc", "(.)+").Groups;
      var captures = groups[1].Captures.ToArray();
      var output = string.Join<Capture>(","), captures);
      Console.WriteLine(output);
      // 输出:a,b,c
      

Multiple outputs from T4 made easy – revisited

Copyright ©Bota5ky all right reserved,powered by GitbookLast Updated: 2023-11-13 09:41:56

results matching ""

    No results matching ""