【问题标题】:Java regex : Remove (double) negative look ahead and look behindJava 正则表达式:删除(双重)否定的向前看和向后看
【发布时间】:2017-08-12 03:05:32
【问题描述】:

我有以下将字符串与模式匹配的正则表达式:

(?i)(?<![^\\s\\p{Punct}]):往后看

(?![^\\s\\p{Punct}]):往前看

下面是一个演示我如何使用它的示例:

public static void main(String[] args) {
    String patternStart = "(?i)(?<![^\\s\\p{Punct}])", patternEnd = "(?![^\\s\\p{Punct}])";
    String text = "this is some paragraph";
    System.out.println(Pattern.compile(patternStart + Pattern.quote("some paragraph") + patternEnd).matcher(text).find());
}

它返回true,这是预期的结果。然而,由于regex 使用双重否定(即否定的向前/向后和^),我认为删除这两个否定应该返回相同的结果。所以,我尝试了以下方法:

String patternStart = "(?i)(?<=[\\s\\p{Punct}])", patternEnd = "(?=[\\s\\p{Punct}])";

但是,它似乎没有按预期工作。我什至尝试在(方括号的)末尾添加^ 和/或$ 以匹配字符串的开头/结尾,但仍然没有运气。

是否可以将这些regexes 转换为正向查找?

【问题讨论】:

  • (?=[\\s\\p{Punct}])(?![^\\s\\p{Punct}]) 不同
  • 两个负数就是一个正数。但是,如果使用否定字符类来排除超类的子类,则需要小心。示例[^\P{Punct},.] 另外,请注意,使用两个底片具有传递锚点的隐藏优势。所以空白边界是(?&lt;!\S)(?!\S)

标签: java regex string pattern-matching


【解决方案1】:

是的,这是可能的,但它的效率低于你所拥有的,因为在积极的环顾中你需要使用 alternation

String patternStart = "(?i)(?<=^|[\\s\\p{Punct}])", patternEnd = "(?=[\\s\\p{Punct}]|$)";
                               ^^                                                   ^^ 

(?&lt;=^|[\\s\\p{Punct}]) 后视要求存在字符串开头 (^) 或 | 空格或标点符号 ([\\s\\p{Punct}])。正向前瞻 (?=[\\s\\p{Punct}]|$) 需要空格或标点符号,或字符串结尾。

如果您只是将^$ 添加到[\\s\\p{Punct}^][\\s\\p{Punct}$] 等字符类中,它们将被解析为文字插入符号和美元符号。

【讨论】:

  • 啊,好吧,我尝试在方括号内使用[\\s\\p{Punct}^][\\s\\p{Punct}$],希望它们能以其他模式得到ORed。现在一切都说得通了,再次感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-03
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多