我正在尝试使用以下模式解析数据行:
1337; GROUP; VARIABLE; 13.37; key = value; key = value; key = value ...(依此类推)
基本上是Number?;Name?;Name?;Value;(key=value)*
。
;
分隔符可以设置为任何字符串。例如,如果将其设置为FOO
,则此行数据将被视为有效:
1337FOOGROUPFOOVARIABLEFOO13.37FOOkey =值
由于只有Value
是强制性的,因此该行也被视为有效:
FOOFOOFOO13.37
我尝试过以下测试代码:
private static final String BASE_PAYLOAD_DATA = "\\s*(\\d*SEPNOTSEP*SEPNOTSEP*SEPNOTSEP+(?:SEPNOTSEP*=NOTSEP*)*)\\s*$";
public static void main(String[] args) {
String line = "1337;GROUP;VARIABLE;13.37;key=value";
String separator = ";";
String processed = StringUtils.replace(BASE_PAYLOAD_DATA, "NOTSEP", "(?!" + separator + ")");
processed = StringUtils.replace(processed, "SEP", "(?:" + separator + ")");
System.out.println(processed);
Pattern payloadData = Pattern.compile(processed);
System.out.println(payloadData.matcher(line).matches());
}
但测试线不匹配。 SEP
和NOTSEP
字符串用于模拟可以配置分隔符的事实。
输出:
\s*(\d*(?:;)(?!;)*(?:;)(?!;)*(?:;)(?!;)+(?:(?:;)(?!;)*=(?!;)*)*)\s*$
false
我对模式进行了两次和三次检查,但我似乎无法指出错误的元素,我担心我可能会错过一些太明显的东西。
或者是否有关于我失踪的非录音和负面预测组的行为?
另外,是否有更优雅的方式来声明正则表达式模式?
谢谢!
修改
似乎是从这个Regex Tutorial:
前瞻本身不是捕获组。它不包括在对反向引用进行编号的计数中。如果你想将正则表达式的匹配存储在一个先行中,你必须在前瞻内部的正则表达式周围放置捕获括号,如下所示:(?=(regex))。
我会试一试。
答案 0 :(得分:1)
围绕具有非捕获组的负向前瞻组,每个组都可以量化,因为我在编辑中链接了{Regex Tutorial):
前瞻本身不是捕获组。它不包括在对反向引用进行编号的计数中。如果你想将正则表达式的匹配存储在一个先行中,你必须在前瞻内部的正则表达式周围放置捕获括号,如下所示:(?=(regex))。
我最终决定使用限制较少的正则表达式,使用分隔符拆分行并使用更基于Java的方法分析标记(比较标记等)。
答案 1 :(得分:0)
我认为你认为(?!X)'分号的负前瞻'与'不是分号'[^;]相同。 只是出于好奇,你为什么要使用(?:;)而不是非捕获组呢? 我认为这对你有用Java SE 7 Pattern