2013-08-27 91 views
1

示例代码:Java的模式正则表达式

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Regex { 
public static void main(String[] args) { 
    String data = ". Shyam and you. You are 2.3 km away from home. Lakshmi and you. Ram and you. You are Mike. "; 
    Pattern pattern = Pattern.compile("(?<=\\.\\s)(.*?are.*?)(?=\\.\\s)"); 
    Matcher matcher = pattern.matcher(data); 
    while (matcher.find()) { 
     System.out.println(matcher.group(1)); 
     } 
    } 
} 

所需的输出

您有2.3公里,从家里

你是迈克

但真正的输出是

Shyam和你。你距离家2.3公里远

Lakshmi和你。拉姆和你。你是迈克

请帮忙。

+0

参见:http://stackoverflow.com/questions/1232220/how-to-non-greedy-multiple-lookbehind-matches –

+0

是否有一个原因,'你已经有2.3公里home.'发生输入两次,只输出一次? – Thomas

+0

提示:'^'和'$'允许您捕获字符串的开头和结尾 –

回答

2

您的表情与第一个点匹配,并且.*?也会匹配点。因此,您可以获得Shyam and you...作为匹配。尝试更改(.*?are.*?)([^\\.]*?are[^\\.]*?)以匹配除点之外的所有字符。

请注意,您还可以将表达式简化为\s*([^\.]*are[^\.]*)(此处为非Java符号)。这会有相同的结果,但也会匹配"You are Shyam. You are Mike."

该表达式可以匹配不包含点的字符序列与中间的“are”之间的任意空格。请注意,这也将单独匹配are,因此您可能需要将[^\.]*更改为[^\.]+

编辑

为了考虑您的更新例如,你可以试试这个表达式(休息下来如下):

\s*((?:[^\.]|(?:\w+\.)+\w)*are.*?)(?:\.\s|\.$)

输入:I am here. You are almost 2.3 km away from home. You are Mike. You are 2. 2.3 percent of them are 2.3 percent of all. Sections 2.3.a to 2.3.c are 3 sections. This is garbage.

输出:You are almost 2.3 km away from homeYou are MikeYou are 2,2.3 percent of them are 2.3 percent of all,Sections 2.3.a to 2.3.c are 3 sections

一些注意事项:这将需要每个句子以一个圆点结尾(这可以通过用[.!?]\s|[.!?]$替换\.\s|\.$来更改),每个分隔点后跟一个空格或输入的结尾,并且不匹配You are J. J. Abrams2.a

请注意,在这种情况下,计算机确实很难确定句子结尾,特别是使用“简单”正则表达式。

表达分解:

  • \s*前导空白不会是组的一部分,否则这是没有必要
  • ((?:[^\.]|(?:\w+\.)+\w)*are.*?)捕获的组,之前和之后包含are和附加的文本
    • (?:[^\.]|(?:\w+\.)+\w)一个非捕获组匹配任何非点字符序列([^\.])或(|)a字序列字符(\w作为[a-zA-Z0-9_]单点之间(快捷方式)(?:\w+\.)+\w),也非捕获)
    • .*?字符但具有懒惰改性剂的任何序列匹配最短的序列,而不是最长(没有它,下一个部分将没有多大意义)
  • (?:\.\s|\.$)必须遵循所捕获的基团的非捕获组,它必须或者在输入的结束相匹配的点,接着空格(\.\s)或(|)的点(\.$

编辑2

这里的无(A|B)*基团的不彻底的测试版本:

\s*([^.]*(?:(?:\w+\.)+\w+[^.]*)*are.*?)(?:[.!?]\s|[.!?]$)

基本上(?:[^\.]|(?:\w+\.)+\w)*已被替换为[^.]*(?:(?:\w+\.)+\w+[^.]*)*,意思是“非点的字符的任何序列,随后通过任意数量的由点字围绕的点组成的序列,然后是任何非点字符序列“。 ;)

+0

我编辑了我的问题来更改示例字符串。 请看看它。 我认为你可以解决我的问题:) – user2722117

+0

这就是我想要的:) 谢谢托马斯:) – user2722117

+0

我试着用我的原始数据(约800句话)你的正则表达式。 它导致溢出错误。 在搜索关于相同。我开始知道(A | B)*像我们的正则表达式中的模式会导致错误。反正有没有这样做一个正则表达式? – user2722117

0

试试这个正则表达式:

"[\\. ]([^\\. ]* are [^\\. ]*)[\\. ]" 
+0

例如:你和jm。你距离家2.3公里。你可以做到这一点。 我希望正则表达式能够与这个例子一起工作。 – user2722117

+0

@ user2722117你真的不清楚你在评论中想说什么。把东西放在引号或代码刻度中来分隔你的附加例子。 – AJMansfield

+0

@AJMansfield是的,我也和我以前的评论一样。 反正,我用相同的例子更新了我的问题:) – user2722117

0

您可以尝试正则表达式:

You are (\d+(\.\d+)?|\w+|)* 

Regular expression visualization

例如为:

private static final Pattern REGEX_PATTERN = 
     Pattern.compile("You are (\\d+(\\.\\d+)?|\\w+|)*"); 

public static void main(String[] args) { 
    String input = ". Shyam and you. You are 2.3 km away from home. Lakshmi and you. Ram and you. You are Mike. "; 

    Matcher matcher = REGEX_PATTERN.matcher(input); 
    while (matcher.find()) { 
     System.out.println(matcher.group()); 
    } 
} 

输出:

You are 2.3 km away from home 
You are Mike 
+0

很好的可视化。为了未来读者的利益,这来自[Debuggex.com](http://www.debuggex.com/)。 – dimo414