快速入门
教程
工具和语言
示例
参考
书籍评论
示例
正则表达式示例
数字范围
浮点数
电子邮件地址
IP 地址
有效日期
数字日期转文本
信用卡号
匹配完整行
删除重复行
编程
两个相邻单词
陷阱
灾难性回溯
重复过多
拒绝服务
使所有内容都可选
重复捕获组
混合 Unicode 和 8 位
本网站的更多内容
简介
正则表达式快速入门
正则表达式教程
替换字符串教程
应用程序和语言
正则表达式示例
正则表达式参考
替换字符串参考
书籍评论
可打印 PDF
关于本网站
RSS 源和博客
RegexBuddy—The most comprehensive regular expression library!

匹配常见编程语言结构的正则表达式示例

正则表达式非常适用于在文本编辑器中操作源代码基于正则表达式的文本处理工具中操作源代码。大多数编程语言都使用类似的结构,例如关键字、注释和字符串。但通常存在一些细微差别,这使得使用正确的正则表达式变得很棘手。从下面的示例列表中选择正则表达式时,请务必阅读每个正则表达式的描述,以确保选择正确的正则表达式。

除非另有说明,否则以下所有示例均假定匹配换行符,并且插入符号和美元确实匹配嵌入式换行符。在许多编程语言中,这意味着单行模式必须关闭,并且多行模式必须开启。

单独使用时,这些正则表达式可能无法达到预期结果。如果注释出现在字符串中,则注释正则表达式会将字符串中的文本视为注释。字符串正则表达式还将匹配注释中的字符串。解决方案是使用多个正则表达式并将它们组合成一个简单的解析器,如下面的伪代码所示

GlobalStartPosition := 0;
while GlobalStartPosition < LengthOfText do
  GlobalMatchPosition := LengthOfText;
  MatchedRegEx := NULL;
  foreach RegEx in RegExList do
    RegEx.StartPosition := GlobalStartPosition;
    if RegEx.Match and RegEx.MatchPosition < GlobalMatchPosition then
      MatchedRegEx := RegEx;
      GlobalMatchPosition := RegEx.MatchPosition;
    endif
  endforeach
  if MatchedRegEx <> NULL then
    // At this point, MatchedRegEx indicates which regex matched
    // and you can do whatever processing you want depending on
    // which regex actually matched.
  endif
  GlobalStartPosition := GlobalMatchPosition;
endwhile

如果你在 RegExList 中放入一个匹配注释的正则表达式和一个匹配字符串的正则表达式,那么你可以确保注释正则表达式不会匹配字符串中的注释,反之亦然。在循环中,你可以根据匹配是注释还是字符串来处理匹配。

另一种解决方案是组合正则表达式:(注释)|(字符串)。此 交替 与上面代码片段的效果相同。迭代此正则表达式的所有匹配。在循环中,检查哪个捕获组找到了正则表达式匹配。如果组 1 匹配,则你有注释。如果组 2 匹配,则你有字符串。然后根据该匹配进行处理。

你可以使用此技术构建一个完整的解析器。添加正则表达式以匹配你想要解析的语言或文件格式中的所有词法元素。在循环中,跟踪匹配的内容,以便可以根据其上下文处理以下匹配。例如,如果需要平衡大括号,则在匹配到左大括号时增加计数器,在匹配到右大括号时减少计数器。如果计数器在任何时候变为负数,或者在到达文件末尾时不为零,则引发错误。

注释

#.*$ 匹配以 # 开头并一直持续到 行尾 的单行注释。类似地,//.*$ 匹配以 // 开头的单行注释。

如果注释必须出现在 行首,请使用 ^#.*$。如果行首和注释之间只允许有 空白,请使用 ^\s*#.*$。C 中的编译器指令或编译器伪指令可以用这种方式匹配。请注意,在最后一个示例中,任何前导空白都将是正则表达式匹配的一部分。使用 捕获括号 来分隔空白和注释。

/\*.*?\*/ 匹配 C 样式的多行注释,前提是你打开了 匹配换行符的选项。一般语法为 开始.*?结束。C 样式注释不允许嵌套。如果“开始”部分出现在注释中,它将被忽略。一旦找到“结束”部分,注释就关闭。

如果你的编程语言允许嵌套注释,则没有直接的方法可以使用正则表达式来匹配它们,因为正则表达式无法计数。需要额外的逻辑。

字符串

"[^"\r\n]*" 匹配单行字符串,不允许引号字符出现在字符串内。使用否定字符类比使用惰性点更有效率。"[^"]*" 允许字符串跨越多行。

"[^"\\\r\n]*(?:\\.[^"\\\r\n]*)*" 匹配单行字符串,其中引号字符可以出现,如果它被反斜杠转义。虽然这个正则表达式看起来比它需要的更复杂,但它比更简单的解决方案快得多,这些解决方案可能会导致大量回溯,如果一个双引号单独出现,而不是作为字符串的一部分。"[^"\\]*(?:\\.[^"\\]*)*" 允许字符串跨越多行。

您可以调整上述正则表达式以匹配由两个(可能不同)字符分隔的任何序列。如果我们使用 b 作为起始字符,e 作为结束字符,x 作为转义字符,则不带转义符的版本将变为 b[^e\r\n]*e,而带转义符的版本将变为 b[^ex\r\n]*(?:x.[^ex\r\n]*)*e

数字

\b\d+\b 匹配正整数。不要忘记 词边界[-+]?\b\d+\b 允许有符号。

\b0[xX][0-9a-fA-F]+\b 匹配 C 样式十六进制数。

((\b[0-9]+)?\.)?[0-9]+\b 匹配整数以及带可选整数部分的浮点数。 (\b[0-9]+\.([0-9]+\b)?|\.[0-9]+\b) 匹配带可选整数和可选小数部分的浮点数,但不匹配整数。

((\b[0-9]+)?\.)?\b[0-9]+([eE][-+]?[0-9]+)?\b 匹配科学记数法中的数字。尾数可以是整数或浮点数,整数部分可选。指数部分可选。

\b[0-9]+(\.[0-9]+)?(e[+-]?[0-9]+)?\b 也匹配科学记数法中的数字。与上一个示例的不同之处在于,如果尾数是浮点数,则整数部分是必需的。

如果您阅读了 浮点数示例,您会注意到上述正则表达式与那里使用的正则表达式不同。上述正则表达式更加严格。它们使用单词边界来排除作为其他事物(如标识符)一部分的数字。您可以在所有上述正则表达式之前添加 [-+]? 以在正则表达式中包含一个可选符号。我上面没有这样做,因为在编程语言中,+ 和 - 通常被认为是运算符,而不是符号。

保留字或关键字

匹配保留字很容易。只需使用 交替 将它们串在一起:\b(first|second|third|etc)\b 同样,不要忘记 单词边界