我需要什么Java正则表达式才能匹配此文本?

时间:2009-08-14 14:17:34

标签: java regex parsing

我正在尝试使用Java中的正则表达式匹配以下内容 - 我有一些数据由两个字符'ZZ'分隔。每个记录以'ZZ'开头并以'ZZ'结束 - 我想匹配一个没有结尾'ZZ'的记录,例如,我想匹配下面的尾随'ZZanychars'(注意:*不包含在字符串 - 它们只是标记我要匹配的位。)

ZZanycharsZZZZanycharsZZ的 ZZanychars

但我不希望以下内容匹配,因为记录已经结束:

ZZanycharsZZZZanycharsZZZZanycharsZZ

编辑:澄清事情 - 这是我正在使用的两个测试用例:

// This should match and in one of the groups should be 'ZZthree'
String testString1 = "ZZoneZZZZtwoZZZZthree";

// This should not match
String testString2 = "ZZoneZZZZtwoZZZZthreeZZ";

编辑:添加第三个测试:

// This should match and in one of the groups should be 'threeZee'
String testString3 = "ZZoneZZZZtwoZZZZthreeZee";

6 个答案:

答案 0 :(得分:3)

(在第3个例子的帖子后编辑)

尝试:

(?!ZZZ)ZZ((?!ZZ).)++$

演示:

import java.util.regex.*;

public class Main {
    public static void main(String[] args) {
        String[] tests = {
            "ZZoneZZZZtwoZZZZthree",
            "ZZoneZZZZtwoZZZZthreeZZ",
            "ZZoneZZZZtwoZZZZthreeZee"
        };
        Pattern p = Pattern.compile("(?!ZZZ)ZZ((?!ZZ).)++$");
        for(String tst : tests) {
            Matcher m = p.matcher(tst);
            System.out.println(tst+" -> "+(m.find() ? m.group() : "no!"));
        }
    }
}

答案 1 :(得分:2)

仅匹配最终的未终止记录:

(?<=[^Z]ZZ|^)ZZ(?:(?!ZZ).)++$

起始分隔符是两个Z,但可以有第三个Z被认为是数据的一部分。 lookbehind确保您不匹配前一个记录的结束分隔符的Z(因为结束分隔符可以前面有非分隔符Z) 。但是,这假设永远不会有空记录(或只包含一个Z的记录),这可能导致连续八个或更多Z

ZZabcZZZZdefZZZZZZZZxyz

如果可能,我会忘记尝试自己匹配最终记录,而是从头开始匹配所有

(?:ZZ(?:(?!ZZ).)*+ZZ)*+(ZZ(?:(?!ZZ).)++$)

最终的未终结记录现已在第1组中捕获。

答案 2 :(得分:1)

我建议像......

/ZZ(.*?)(ZZ|$)/

这将匹配:

  1. ZZ - 文字字符串
  2. (.*?) - anychars
  3. (ZZ|$) - 另一个ZZ文字,或字符串
  4. 的结尾

答案 3 :(得分:1)

^ZZ.*(?<!ZZ)$


Assert position at the beginning of the string «^»
Match the characters “ZZ” literally «ZZ»
Match any single character that is not a line break character «.*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Assert that it is impossible to match the regex below with the match ending at this position (negative lookbehind) «(?<!ZZ)»
   Match the characters “ZZ” literally «ZZ»
Assert position at the end of the string (or before the line break at the end of the string, if any) «$»


Created with RegexBuddy

答案 4 :(得分:0)

这有一个棘手的部分:ZZ既是开始令牌又是结束令牌。

有一个开始案例(ZZ,未跟随另一个ZZ表示第一个ZZ实际上是结束标记),以及两个结束案例(ZZ结束字符串,ZZ后跟ZZ)。目标是匹配起始案例而不是最终案例。

为此,我建议这样做:

/ZZ(?!ZZ)(.*?)(ZZ(?!(ZZ|$))|$)/

对于字符串ZZfooZZZZbarZZbazZZ

  • 这不会匹配ZZfooZZ,一个合法的记录:ZZ,后面没有ZZ,后跟任意字符组合(此处为“foo”),后跟ZZ,但ZZ后面是ZZ,后面打开下一条记录
  • 检查的下一部分是foo之后的ZZ。这失败是因为ZZ不能跟随另一个ZZ,但在这种情况下它是。这是我们想要的,因为在foo之后的ZZ无论如何都不会开始新的记录。
  • ZZ之前的ZZ没有跟随另一个ZZ,所以这是一个合法的记录开始。 “bar”被。*?消耗。然后有一个ZZ,但它没有跟着另一个ZZ或字符串的结尾,这意味着ZZbar令牌不好。
    • (它可以被人类解释为ZZbarZZ,bazZZ无效,但无论哪种情况都有问题,所以我只是写了正则表达式来考虑错误格式的记录在这里发生)
    • 所以ZZbar将被正则表达式捕获/匹配,因为它是非法的。
  • ZZ之后的ZZ后面没有ZZ,接着是baz,接着是ZZ,它没有前瞻断言,说明它不能跟着字符串的末尾。所以ZZbazZZ是一个合法的记录,并没有在正则表达式中捕获。

还有一个案例:对于ZZfoo,开始ZZ没问题,foo被捕获,然后正则表达式注意到它是字符串的结尾,并且没有发生ZZ。因此,ZZfoo被捕获为非法比赛。

如果这没有意义,请告诉我,所以我可以说得更清楚。

答案 5 :(得分:0)

如何尝试删除ZZallcharsZZ的所有匹配项以及您剩下的就是您想要的。

ZZ.*?ZZ