远看的负面看法

时间:2013-01-31 12:36:45

标签: java regex

如何更改pattern以进一步查看字符串?

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

例如,这将有 5场比赛

  

代表行为(a),(b),(c),(d)或(a)所述的任何人行事   (e)(f)段;

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

这将有 0匹配

  

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

3 个答案:

答案 0 :(得分:2)

对于任何具有简单外观的长度来说,这是不可能的。 Java正则表达式风格只允许有限长度的lookbehind(即你可以(?<=x{2,10})而不是(?<=x*))。

如果您可以将问题缩小为“单词paragraph不应出现在(a)之前的100个字母中”,那么该作品有效:

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

如果你真的想要无限距离,如果你的正则表达式是灵活的并且可以从输入的开始处开始并且只匹配一个(ref),你可以用负面的外观来估计想要的行为-ahead(不需要有限):

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

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

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

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

答案 1 :(得分:1)

你可以这样做:

(我忽略了大小写密集的部分,你可以自己添加)

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

这是检查您的FALSE案例是否匹配。也就是说,(a)前面有paragraph

然后检查线是否与上面的正则表达式匹配,如果为true,则跳过,如果为false,则接受它。

用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)

如果该行没有Paragraph且没有(a),则会遇到一些问题。我认为这也很容易通过类似的东西在你的java程序中修复:

if (!m.find() && line.indexOf("(a)")>0) ...your match   

答案 2 :(得分: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>)。这适用于字符串的任何长度。