0

我有这样的字符串:

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=";

所以,在形式上 - 字符串包含字典中的一些单词定义,用“|”分隔 象征。

这里:

  • word - 字典中的单词(可选,如 S2 或 S3)

  • PS1、PS2、PS3 - 词性标签(必需)

  • p1,p2,... - 一些参数(可选)

  • q1, q2, q3, ... - 一些其他参数(也是可选的)

我想构建正则表达式,它会在文本中找到所有出现的此类字符串并为我提供组:

  • group1 - 单词
  • group2 - 词性标签
  • group3, group4, ... - 参数 p
  • group(k), group(k+1), ... - 另一个参数 (q)

我不关心最后一个 p 参数和第一个 q 参数的组索引。我应该知道,第一组 - 是单词(可能为空),第二组 - 词性,其他组 - 参数 p 和 q。

现在我有这样的正则表达式:

"([a-z]*)?=([A-Z]+)(,?[a-z]+)*=(,?[a-z]+)*")

但它不能正常工作。它只显示了最后一个参数 p 和 q。即(对于 S2):

  • group1 = word3 - 好的
  • 组 2 = PS2 - 好的
  • group3 = p8 - 不正常(仅最后一个 p 参数)
  • group4 = q6 - 不正常(也是最后一个 q 参数)

你可以帮帮我吗?

更新:“=”-字符仅是 p 参数和 q 参数之间的拆分字符。在我的问题中没有必要。您应该认为,p 参数和 q 参数没有什么不同。

实际输入示例:

String s = "bread=NOUN,plur,link=form|=VERB="
4

2 回答 2

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...
}

我曾经[^|=,]*匹配任何非特殊字符。

于 2011-05-02T20:47:33.930 回答
1

当我遇到这样的问题时,我会查看量词上的修饰符。您可能希望将某些量词修改为贪婪,例如

(,?[az]+)+*

上面的这个区别是最后的零个或多个量词现在尽可能多地抓取。这只是一个示例,我完全不确定该特定修饰符是否是您所需要的,但鉴于您的表达式按您报告的那样工作,这些修饰符似乎很可能会在剩下的时间里得到它。

于 2011-05-02T20:42:16.157 回答