【问题标题】:Regular expression to match EOF匹配EOF的正则表达式
【发布时间】:2010-11-13 08:45:56
【问题描述】:

我有一些看起来像这样的数据:

john, dave, chris
rick, sam, bob
joe, milt, paul

我正在使用这个正则表达式来匹配名称:

/(\w.+?)(\r\n|\n|,)/

这在大多数情况下都有效,但文件在最后一个单词之后突然结束,这意味着最后一个值不会以 \r\n\n, 结尾。它以 EOF 结束。有没有办法在正则表达式中匹配 EOF,这样我就可以把它放在第二个分组中?

【问题讨论】:

  • 您是要捕获一个组中的所有名称还是每个名称一个捕获组?
  • 在遇到正则表达式问题时要做的一件事就是单独尝试模式中的元素。如果您担心最后的令牌,请在没有它​​的情况下测试您的表达。
  • 只是想添加一个很棒的正则表达式测试站点:regexplanet.com/simple
  • @Sinan - 我同意;合并

标签: regex


【解决方案1】:

这个问题的答案是\Z 我花了一段时间才弄明白,但现在可以了。请注意,相反,\A 匹配整个字符串的开头(而不是 ^$ 匹配一行的开头)。

【讨论】:

  • 如果您在netbeans 中使用项目文件搜索而不是文件搜索,请注意,以下将行为不同...(\s*)\?>(\s*)\Z ...经过更多挖掘后,这里是对项目文件夹起作用的方法:(\s*)\?>(\s*)(\n*)(\W)\Z 仅供参考:这是用文件末尾的换行符替换所有关闭的 php 标签。
  • 原来\A 也适用于 Visual Studio 查找和替换。一如既往地谨慎使用这些东西,但是一旦我很高兴它实际上会做正确的事情,它就为我节省了大量的手动操作。
  • 当我使用 Java 的 Scanner 类一次读取整个文件时;如果我使用\Z 作为分隔符,尾随换行符被修剪。当我将分隔符更改为\z 时,保留了尾随换行符。看来Martin Dorey's answer也适用于Java。
【解决方案2】:

EOF 实际上不是一个字符。如果你有一个多行字符串,那么 '$' 将匹配字符串的结尾以及行的结尾。

在 Perl 及其兄弟中,\A\Z 匹配字符串的开头和结尾,完全忽略换行符。

对 POSIX 正则表达式的 GNU 扩展使用 \`\' 来做同样的事情。

【讨论】:

    【解决方案3】:

    在 Visual Studio 中,您可以像这样找到 EOF:$(?![\r\n])。无论您的行尾是 CR、CRLF 还是 LF,这都有效。

    作为奖励,您可以确保所有代码文件都有一个最终的换行符,如下所示:

                   Find What: (?<![\r\n])$(?![\r\n])
                Replace With: \r\n
     Use Regular Expressions: checked
    Look at these file types: *.cs, *.cshtml, *.js
    

    这是如何工作的:

    查找前面没有 CR 或 LF 且后面也没有 CR 或 LF 的任何行尾(零宽度匹配)。一些想法会告诉你为什么这样做!

    请注意,您应该替换为所需的行尾字符,无论是 CR、LF 还是 CRLF。

    【讨论】:

    • Visual Studio 2019 中存在一个错误,在该错误中,用它进行全部替换可能会导致在文件末尾添加两个换行符。我认为这与保存选项时自动插入换行符有关。
    • @Stevoisiak 这可能是由插入错误的换行模式引起的。例如,我您的 IDE 正在寻找 \r\n 而您只输入 \n,它可能无法检测到“两个换行符”。
    【解决方案4】:

    对比Ryan's suggested \Z with \z的行为:

    $ perl -we 'my $corpus = "你好\n"; $corpus =~ s/\Z/world/g; print(":$corpus:\n")' :你好世界 世界: $ perl -we 'my $corpus = "你好\n"; $corpus =~ s/\z/world/g; print(":$corpus:\n")' :你好 世界:

    perlresez:

    \Z 仅匹配字符串末尾或末尾换行符之前 \z 仅匹配字符串末尾

    将测试用例翻译成 Ruby(1.8.7、1.9.2)的行为相同。

    在评论中,mmdemirbas adds 说 Java 是一样的。

    【讨论】:

      【解决方案5】:

      对于 JavaScript:

      var matchEndOfInput = /$(?![\r\n])/gm;
      

      基本上这将匹配行尾,后面没有回车符或换行符。本质上,这与 \Z 相同,但适用于 JavaScript。

      【讨论】:

        【解决方案6】:

        也许试试 $ (EOL/EOF) 而不是 (\r\n|\n)?

        /\"(.+?)\".+?(\w.+?)$/
        

        【讨论】:

          【解决方案7】:

          如果你不需要捕获行分隔符,这个正则表达式应该是你所需要的:

          /\w+/
          

          假设您要匹配的所有子字符串完全由单词字符组成,就像在您的示例中一样。

          【讨论】:

            【解决方案8】:

            假设您使用适当的修饰符强制将字符串视为一个整体(不是逐行 - 如果 \n 适合您,则您正在使用它),只需添加另一个替代方案 - 字符串结尾: (\r \n|\n|,|$)

            【讨论】:

              【解决方案9】:

              /(\w.+?)(\r\n|\n|,|$)/

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-03-30
                • 2011-05-01
                相关资源
                最近更新 更多