2012-11-11 89 views
2

我有一些文本;我想提取未被标点符号分隔的单词对。这是代码:Java正则表达式跳过匹配

//n-grams 
Pattern p = Pattern.compile("[a-z]+"); 
if (n == 2) { 
    p = Pattern.compile("[a-z]+ [a-z]+"); 
} 
if (n == 3) { 
    p = Pattern.compile("[a-z]+ [a-z]+ [a-z]+"); 
} 
Matcher m = p.matcher(text.toLowerCase()); 
ArrayList<String> result = new ArrayList<String>(); 

while (m.find()) { 
    String temporary = m.group(); 
    System.out.println(temporary); 

    result.add(temporary); 
} 

问题是它跳过一些匹配。例如

“我的名字是詹姆斯”

,n = 3时,必须匹配

“我的名字是” 和 “的名字是詹姆斯”

,但它只是匹配第一个。有没有办法解决这个问题?

回答

4

你可以用它组先行

(?=(\b[a-z]+\b \b[a-z]+\b \b[a-z]+\b)) 

这使得它有两种groups..So你的情况来捕捉这将是

Group1->my name is

Group2-捕捉>name is james

+3

+1我知道**有更好的方法。 –

1

在由正则表达式定义的正则表达式模式中,从左向右应用字符串,并且一旦在匹配中使用了源字符,就不能重用它。

例如,正则表达式“121”将仅匹配“31212142121”两次作为“ ___121”。

+0

有没有办法解决这个问题? –

+0

不,你可以通过在'group'中使用'lookahead'来捕获它,就像这样('=?(121))' – Anirudha

+0

我不知道我们可以重复使用已使用的单元。你可以尝试split()方法来实现这一点。 – Pankaj

1

我倾向于使用find()方法的参数Matcher

Matcher m = p.matcher(text); 
int position = 0; 
while (m.find(position)) { 
    String temporary = m.group(); 
    position = m.start(); 
    System.out.println(position + ":" + temporary); 
    position++; 
} 

所以在每次迭代之后,它会根据最后一个开始索引再次搜索。

希望有帮助!

+1

这匹配“名称是债券”,“阿姆是债券”,“我是债券”... :) –

+0

哦!对!我正在考虑另一种类型的正则表达式,比如像'abababa'这样的字符串中搜索一个像'aba'这样的字符串。做_my way_解决问题并查找所有事件。很抱歉对于这个误会!你肯定需要另一种方法。 –