您所拥有的是Friedl的“展开循环”技术的一个示例,但是您似乎对如何将其表示为字符串文字感到困惑。这是正则表达式编译器的外观:
"[^"\]*(?:\.[^"\]*)*"
首字母
"[^"\]*与引号匹配,后跟零个或多个除引号或反斜杠之外的任何字符。仅此部分以及最终部分
"将匹配一个简单的带引号的字符串,且没有嵌入的转义序列,例如
"this"或
""。
如果 确实
遇到反斜杠,则
\.消耗反斜杠及其后的所有内容,并且
[^"\]*(再次)消耗掉直到下一个反斜杠或引号的所有内容。该部分将根据需要重复多次,直到出现未转义的引号(或到达字符串的末尾并且匹配尝试失败)为止。
请注意,这将
"foo"-在中匹配
"foo"-"bar"。这似乎暴露了正则表达式中的缺陷,但事实并非如此。这是无效的 输入
。目标是匹配带引号的字符串(可选地包含嵌入在其他文本中的反斜杠转义的引号)—为什么引号字符串 之外
的转义引号?如果您确实需要支持,那么您会遇到一个更加复杂的问题,需要一种截然不同的方法。
就像我说的,上面是正则表达式对正则表达式编译器的外观。但是,您是以字符串文字的形式编写它的,而这些字符串往往会特别对待某些字符,即反斜杠和引号。幸运的是,C#的逐字字符串免除了您必须两次转义反斜杠的麻烦。您只需要用另一个引号将每个引号引起来:
Regex r = new Regex(@"""[^""\]*(?:\.[^""\]*)*""");
因此,规则是C#编译器使用双引号,而regex编译器使用双反斜杠-
既好又简单。这个特殊的正则表达式可能看起来有些尴尬,在两端都带有三个引号,但是请考虑以下选择:
Regex r = new Regex(""[^"\\]*(?:\\.[^"\\]*)*"");在Java中,您 始终 必须以这种方式编写它们。:-(



