Bota5ky

正则表达式

匹配模式

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

分组

  • \<no.> 如\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

posted @ 2022-06-24 10:27  Bota5ky  阅读(47)  评论(0)    收藏  举报