1

我有一个字符串:

Single line : Some text
Multi1: multi (Va1)    Multi2 : multi (Va2) Multi3 : multi (Val3)
Dots....20/12/2013 (EOY)

我正在尝试检索所有键值对。我的第一次尝试

(单行|Multi[0-9]{1}|Dots)( *:? [.] *| *:? )(. )

似乎可以工作,但不能在一行上处理多个键值对。有什么办法可以做到这一点?

4

3 回答 3

1

尝试这个:

String text = "Single line : Some text\r\n" + 
"Multi1: multi (Va1)    Multi2 : multi (Va2) Multi3 : multi (Val3)\r\n" +
"Dots....20/12/2013 (EOY)";
Pattern pattern = Pattern.compile("(\\p{Alnum}[\\p{Alnum}\\s/]+?)\\s?(:|\\.+)\\s?(\\p{Alnum}[\\p{Alnum}\\s/]+?)(?=($|\\()|(\\s\\())", Pattern.MULTILINE);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
    System.out.println(matcher.group(1) + "-->" + matcher.group(3));
}

输出:

Single line-->Some text
Multi1-->multi 
Multi2-->multi 
Multi3-->multi 
Dots-->20/12/2013 

解释:

  • 我将键和值限制为“以字母数字开头”、“包含任意数量的字母数字、空格或斜杠”。
  • 我将分隔符限制为“可选空格、:、可选空格”或“可选空格、任意数量的连续点、可选空格”。
  • 我正在使用第 1 组和第 3 组来定义 Pattern.
  • 第 2 组用于提供上述替代分隔符。
  • 最后,Pattern在结尾处分隔,或者用新行,或者用一个开放的圆括号,或者用一个空格,后跟一个开放的圆括号。

请注意,您不能在前瞻或后瞻组中使用量词,因此会重复。

于 2013-07-19T16:34:28.813 回答
1

您可以使用此模式:

public static void main(String[] args) {

    String s = "Single line : Some text\n"
             + "Multi1: multi (Va1)    Multi2 : multi (Va2) "
             + "Multi3 : multi (Val3)\n"
             + "Dots....20/12/2013 (EOY)";

    String wd = "[^\\s.:]+(?:[^\\S\\n]+[^\\s.:]+)*";
    Pattern p = Pattern.compile("(?<key>" + wd + ")"
                              + "\\s*(?::|\\.+)\\s*"
                              + "(?<value>" + wd + "(?:\\s*\\([^)]+\\))?)"
                              + "(?!\\s*:)(?=\\s|$)");
    Matcher m = p.matcher(s);

    while (m.find()) {
        System.out.println(m.group("key")+"->"+m.group("value"));
    }
}
于 2013-07-19T16:09:44.003 回答
0

我不记得确切的语法,但我认为它是这样的:

while (matcher.find()) {
  String match = matcher.group();
}

这里的目标是您需要遍历当前行并告诉它“当您仍在查找内容时,将这一行上匹配的字符串返回给我”。由于您在同一行上有多个匹配项,因此它应该不断为您提取结果。这是 Matcher 的 JavaDoc作为参考。

可悲的是,这也是为什么 Java 真的不适合这种事情的另一个原因,在任何人对我理解之前,我说这是对 Java API 的批评,而不是对语言的批评。

于 2013-07-19T16:07:24.150 回答