【问题标题】:Regular Expression passes for one character sequence whereas fails for another正则表达式对一个字符序列通过,而对另一个字符序列失败
【发布时间】:2016-02-04 21:41:36
【问题描述】:

我正在使用以下正则表达式:

$test="a\n";

if ($test =~ /^.$/ ){
 print "Test Passed\n";
}else{
 print "Test Failed\n";
}   

对于前面提到的测试变量,正则表达式找到模式。

但是,如果我将变量更改为以下值,则无法识别模式。

$test="\na";

我知道我的表达式匹配单个字符,即目标应该以单个字符开头和结尾。

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    简洁的答案

    如果您需要检查字符串是否只有一个字符(任何字符,包括换行符),请使用

    /^.\z/s
    

    说明

    问题源于您使用的$ 没有D 修饰符,这意味着$ 在末尾匹配,而不是在字符串的最末尾匹配。在这里,$ = \Z

    默认情况下,$ 将匹配字符串的结尾和最后一个换行符之前的位置。因此,a\n 通过了if ($test =~ /^.$/ ) 测试,但\na 不会,因为. 无法匹配换行符,并且它不是在末尾,而是在开头(它不会与@987654333 匹配@ 也不是 if ($test =~ /^.$/s ))。

    请注意,您可以使用\z 锚点,这将强制正则表达式引擎匹配字符串的最末端。然后,即使使用 DOTALL 修饰符,两个测试用例也会失败。如果您需要这种行为,请使用/^.\z/。或 /^.\z/s 也匹配单个换行符。

    另外,请参阅Whats the difference between \z and \Z in a regular expression and when and how do I use it?

    【讨论】:

    • 我不明白为什么第一个测试用例通过了,因为输入中有两个字符,即一个 new line 和一个字符 a.
    • 我已经解释过了。 $\Z,匹配在末尾或字符串中最后一个换行符之前。您的字符串 a\n 有 1 个非空白字符,它与 . 匹配。然后,$ 匹配最后一个换行符前面的位置。宾果游戏!
    【解决方案2】:

    你有两个问题。

    首先,$ 不匹配字符串的结尾。在没有/m 标志的情况下,它等同于\Z,它匹配字符串末尾的either 或字符串末尾的换行符之前。

    几乎总是这不是您想要的,您应该使用仅匹配字符串末尾的\z。几乎所有使用

    的代码

    其次,. 默认不匹配任何字符。除非您提供/s 标志,否则它匹配任何字符\n

    所以你的正则表达式 /^.$/ 将匹配:

    1. 不是换行符的单个字符,或
    2. 两个字符,第一个不是换行符,第二个是

    要匹配单个字符,请使用 /^.\z/s(或仅使用 length($string) == 1)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 2018-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多