是否有可能使用Java正则表达式找到动态组的值?

时间:2013-11-17 20:33:12

标签: java regex

如果我有

这样的文字
"Record with text1 Record with text2 Record with text3"

我知道:记录数量将从2到10, 是否可以使用正则表达式?:

Pattern.compile("(Record.*){2,10}");

我怎样才能获得记录的值?

"Record with text1"
"Record with text2"
"Record with text3"
...

3 个答案:

答案 0 :(得分:4)

是的,可以使用正则表达式来捕获您的匹配项。您可以在此处使用否定前瞻断言来查找上一个匹配停止的位置并继续匹配。

String s  = "Record with text1 Record with text2 Record with text3";
Pattern p = Pattern.compile("(?i)\\brecord(?:(?!record).)+");
Matcher m = p.matcher(s);
while (m.find()) {
  System.out.println(m.group());
}

输出

Record with text1 
Record with text2 
Record with text3

正则表达式:

(?i)           set flags for this block (case-insensitive)
 \b            the boundary between a word char (\w) and not a word char
  record       'record'
 (?:           group, but do not capture (1 or more times)
  (?!          look ahead to see if there is not:
    record     'record'
  )            end of look-ahead
  .            any character except \n
 )+            end of grouping

我会考虑split在这种情况下的记录来消耗你的比赛。

String s = "Record with text1 Record with text2 Record with text3";
String[] parts = s.split("(?<!\\A)(?=(?i:record\\b))");
System.out.println(Arrays.toString(parts));

输出

[Record with text1 , Record with text2 , Record with text3]

正则表达式:

(?<!          look behind to see if there is not:
\A            the beginning of the string
)             end of look-behind
(?=           look ahead to see if there is:
 (?i:         group, but do not capture (case-insensitive)
  record      'record'
  \b          the boundary between a word char (\w) and not a word char
 )            end of grouping
)             end of look-ahead

答案 1 :(得分:1)

“使用”正则表达式并不清楚你的意思,但如果你想检查输入包含2-10个“记录”,那么这将有效:

if (input.matches("(Record.*?){2,10}"))

将记录拆分为单独的字符串数组:

String[] records = input.split("(?=Record)");

由于您希望在结果中保留“记录”文本,因此正则表达式无法消费“记录”,因此使用了前瞻。

答案 2 :(得分:0)

如果您的记录分开,那么您可以使用

Pattern.compile("^Record.*");

接下来使用Matcher,您可以创建类似

的内容
while (matcher.find()){
    System.out.println(matcher.group());
}

打印以单词Record开头的所有行。


如果按记录值表示Record之后的部分,那么您可以使用此模式

Pattern.compile("^Record\\s+(.*)");

并在group(1)上调用matcher(这将在第一个括号内返回部分匹配)。


另一种方法是使用预测来确定匹配应停止的位置

Pattern.compile("\\bRecord(.(?!Record))*+");

但这可能使事情过于复杂。如果你的记录之间有一些特殊的字符会更简单,所以我们可以在正则表达式的末尾使用它(现在这个特殊的分隔符是另一个单词Record)。