如何匹配不在段落末尾的句点?

时间:2014-06-28 19:39:31

标签: regex

如果我想找到段落末尾的所有句号,我可以\.($|\n)。但是,我怎么能否定这一点,然后说出一个句号,其后是任何一个ISN' T中的一个,因为元字符不能在字符类中工作,这会阻止我使用否定的字符类? / p>

4 个答案:

答案 0 :(得分:5)

$中的内容是什么?这取决于!

答案很大程度上取决于您使用的语言和正则表达式引擎。你看,

  1. 在Java中,$断言我们位于字符串的末尾,或者在字符串末尾的任何回车符或换行符之前。因此,使用\.(?!$)
  2. 可以确保安全
  3. 在PCRE,C#和Python中,$断言我们位于字符串的末尾或字符串末尾的任何换行符之前。所以你可以使用\.(?!$|\r)
  4. 在JavaScript和Ruby中,$断言我们位于字符串的末尾。因此,您需要使用\.(?!$|[\r\n])
  5. 来完整的Monty

    因此,对于多引擎解决方案,最安全的是:

    \.(?!$|[\r\n])
    

    但在正确的背景下,其他两个选项是完全可以接受的。

    <强>解释

    • \.与文字句点匹配
    • 否定前瞻(?!$|[\r\n])断言后面的内容既不是“字符串的结尾”,也不是回车或换行符。

答案 1 :(得分:4)

使用Negative Lookahead执行此操作。

\.(?!\n|$)

<强>解释

\.          '.'
(?!         look ahead to see if there is not:
  \n          '\n' (newline)
 |           OR
  $           before an optional \n, and the end of the string
)           end of look-ahead

Live Demo

答案 2 :(得分:4)

最有用的速记版本的负面向前EOL检查在这段时间结束后使你的整个模式像这样:

   (?x:           # enable comments
        \.        # a literal dot character
        (?!       # look ahead for not the following{
            \R ?  #    optional EOL grapheme cluster
            \z    #    at the true end of string
        )         # } end look ahead
   )

假设您不希望它与“interstitially”匹配(即,在任何行终止符字形之前),这将更简单:

(?=\R)

可以对\R?作为\R*进行一些论证,以防万一你碰巧在记录的末尾有多个换行符,比如行中的几个换行符。那样,在字符串结束之前允许使用0,1,2或多个EOL字形。

另一方面,很可能一个段落必须至少有两个EOL字素,而不仅仅是一个。例如,在此处的标记和其他具有“空行分隔”类型的段落的文件中都是如此。所以没有EOL可以,两个或更多也是,但不只是其中之一。

对于这样的文本,你需要\R{2,},但整个位都是可选的,在这种情况下会产生:

   (?x:           # enable comments
        \.        # a literal dot character
        (?!       # look ahead for NOT the following {
            (?:
                \R {2,}   # two or more EOL grapheme clusters
            ) ?   #       # optionally
            \z    #    at the true end of string
        )         # } end negated look ahead
   )  

如果你的正则表达式中没有来自UTS 18: Unicode Regular Expressions — Line Boundaries\R,那么你必须用艰难的方式写出来,这很烦人:

 (?x:              # We are emulating \R per UTS#18 
      (?>          # Prohibit backtrack within subpattern
          \r \n    # Match a CRLF without backtracking
                   # or else any code point with the 
                   # vertical space character property
                   # \p{VertSpace}, here enumerated in full 
        | [\x0A-\x0D\x85\x{2028}\x{2029}] 
       )         
 )

你需要no-backtracking位来避免允许\R{2}匹配单个CRLF,并且不允许这样做。

最后要考虑的是,是否要允许可选的水平空格介入期间和EOL之间。我宁愿想象你这么做,但是如果没有更严格的正式规范,就不可能这么说。

答案 3 :(得分:2)

你应该使用负向前瞻。

\.(?!$|\n)

更多相关信息:http://www.regular-expressions.info/lookaround.html

相关问题