我有这样的字符串:
String s = "word=PS1,p1,p2,p3=q1,q2|word2=PS3,p4,p5,p6=q3";
或者像这样:
String s2 = "word3=PS2,p7,p8=q4,q5,q6|=PS3,p9=";
或者像这样:
String s3 = "=PS3=";
所以,在形式中 - 字符串包含字典中的一些单词定义,由“|”分割符号
这里:
单词 - 字典中的单词(可选,如S2或S3)
PS1,PS2,PS3 - 词性标签(必填)
p1,p2,... - 一些参数(可选)
q1,q2,q3,... - 其他一些参数(也是可选的)
我想构建正则表达式,它会在文本中找到所有这些字符串,并为我提供组:
我不关心最后一个p参数和第一个q参数的组索引。我应该知道,第一组 - 是单词(可能为空),第二组 - 词性,以及其他组 - 参数p和q。
现在我有这样的正则表达式:
"([a-z]*)?=([A-Z]+)(,?[a-z]+)*=(,?[a-z]+)*")
但它无法正常工作。它只显示最后一个参数p和q。即(对于S2):
你能帮帮我吗?
更新的: “=” - 仅表示p参数和q参数之间的分割字符。在我的问题中没有必要。您应该认为,p参数和q参数没有区别。
真实输入的例子:
String s = "bread=NOUN,plur,link=form|=VERB="
答案 0 :(得分:2)
Regex中不能有可变数量的捕获组。在.Net中,每个组可以有多个捕获,但不能用Java。问题在于,正则表达式引擎只存储每个组的最后一次成功匹配。你能做的最好的事情是将所有的p-和q-参数匹配成两个大的组,然后将它们分开。
Pattern pattern1 = Pattern.compile(
"([^|=,]*)" + // Group 1: The word. Zero or more characters.
"=([^|=,]*)" + // Group 2: The part of speech.
",?([^|=,]*(?:,[^|=,]*)*)" + // Group 3: The p-params
"=([^|=,]*(?:,[^|=,]*)*)" // Group 4: The q-params
);
Matcher matcher = pattern1.matcher("word=PS1,p1,p2,p3=q1,q2|word2=PS3,p4,p5,p6=q3");
while (matcher.find()) {
String word = matcher.group(1);
String partOfSpeech = matcher.group(2);
String pParamString = matcher.group(3);
String qParamString = matcher.group(4);
String[] pParams = pParamString.split(",");
String[] qParams = qParamString.split(",");
// Do something with the above variables...
}
我使用[^|=,]*
来匹配任何非特殊字符。
答案 1 :(得分:1)
当我遇到这样的问题时,我会关注量词的修饰符。您可能希望将某些量词修改为贪婪,例如
(?,[A-Z] +)+ *
上面的这个差异是,最终零或更多量词现在尽可能多地获得。这只是一个例子,我不能确定那个特定的修饰符是你需要的,但是,鉴于你的表达式就像你报告的那样工作,看起来这些修饰符很可能会让它完全得到它。