1

如何更改我的模式以进一步查看字符串?

当单词“段落”在模式(alpha)后面时,匹配为假,否则为真。

因此,例如,这将有5 个匹配项

代表 (a)、(b)、(c)、(d) 或 (e) (f) 段提及的任何人行事;

他们将是:(a) (b) (c) (d) (e)

这将有0 个匹配项

代表(a)、(b)、(c)、(d)或(e)段提述的任何人行事;

4

3 回答 3

2

对于任何长度的简单回顾,这都是不可能的。Java regex 风格只允许有限长度的lookbehind(即你可以(?<=x{2,10})但不能(?<=x*))。

如果您可以将问题简化为“单词paragraph不应该出现在 . 前面的 100 个字母中(a)”,那就行了:

(?<!paragraph.{0,100})\([a-z]\)

如果您真的想要无限距离,并且您的正则表达式很灵活并且可以从输入的开头开始并且只匹配一个(ref),您可以使用负前瞻(不必是有限的)来近似想要的行为:

^(?!.*?paragraph.*?\([a-z]\)).*?\([a-z]\)

将匹配test test (a)但不匹配paragraph test (a)

这是一个技巧,尽管维护起来可能会变得非常复杂,有缺点(比如只匹配一次),最终可能会有更好的方法来解决你的问题。例如,您可以匹配所有这些,([a-z])然后检查字符串是否包含paragraph,消除其位置之后的所有匹配项。

Pattern.compile("[aA][bB][cC]")PS:考虑使用Pattern.compile("abc", Pattern.CASE_INSENSISIVE)or代替Pattern.compile("(?i)abc")(如果整个正则表达式不区分大小写)或Pattern.compile("(?i:abc)dEf")(如果只是abc不区分大小写)。

于 2013-01-31T13:08:55.737 回答
1

你可以这样做:

(我忽略了案例密集部分,您可以自己添加)

".*Paragraph.*\\(a\\)" 

这是检查您的FALSE情况是否匹配。也就是,(a)前面paragraph有一个。

然后检查该行是否与上面的正则表达式匹配,如果为真,则跳过,如果为假,则接受。

用 grep 测试:(-v 用于显示不匹配的行)

kent$  cat test.txt
(a)
Paragraph (a)
(b) (c)
foo bar Paragraph (a) (b)
foo bar Paragraph (some) (a) (b)
foo bar (a) (b) Paragraph (c)

kent$  grep -v '.*Paragraph.*\(a\)' test.txt
(a)
(b) (c)
foo bar (a) (b) Paragraph (c)

有一个小问题是,如果该行有 noParagraph和 no (a),也会匹配。我认为这也很容易通过以下方式在您的 java 程序中修复:

if (!m.find() && line.indexOf("(a)")>0) ...your match   
于 2013-01-31T13:15:04.050 回答
0

你可以这样做:

// If "paragraph" (case insensitive) does not appear before any (<alpha>)
// It means that "paragraph" (case insensitive) will appear after one (<alpha>)
// OR it does not appear at all in the string.
if (!str.matches("(?s)(?:(?!\\([a-z]+\\)).)*(?i:paragraph).*")) {
    // Use the Matcher loop to extract the text that matches pattern "\\([a-z]+\\)"
    Pattern p = Pattern.compile("\\([a-z]+\\)");
    Matcher m = p.matcher(str);

    while (m.find()) {
        System.out.println(m.group());
    }
}

paragraph在提取(<alpha>)所有(<alpha>). 这适用于任何长度的字符串。

于 2013-01-31T14:30:18.823 回答