2009-07-25 43 views
4

我试图找到文本“箭”的所有匹配ASCII“箭”,所以在查找文本

"<----=====><==->>" 

的箭头是:

"<----", "=====>", "<==", "->", ">" 

这工作:

String[] patterns = {"<=*", "<-*", "=*>", "-*>"}; 
    for (String p : patterns) { 
     Matcher A = Pattern.compile(p).matcher(s); 
     while (A.find()) { 
     System.out.println(A.group()); 
     }   
    } 

但这并不:

 String p = "<=*|<-*|=*>|-*>"; 
     Matcher A = Pattern.compile(p).matcher(s); 
     while (A.find()) { 
     System.out.println(A.group()); 
     }   

不知道为什么。它经常报告"<"而不是"<===="或类似的。

出了什么问题?

+4

你的第二个例子是否曾经做过任何事情?由于`patterns`为空,`for`循环永远不会运行。 – RichieHindle 2009-07-25 21:13:06

+2

第二个例子甚至不会编译。你有两个引用不同类型的“p”变量。 ;-) – 2009-07-25 21:13:56

+0

试试这个“?” – UnkwnTech 2009-07-25 21:14:56

回答

6

下面的程序编译为一个可能的解决方案的问题是:

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

public class A { 
    public static void main(String args[]) { 
    String p = "<=+|<-+|=+>|-+>|<|>"; 
    Matcher m = Pattern.compile(p).matcher(args[0]); 
    while (m.find()) { 
     System.out.println(m.group()); 
    } 
    } 
} 

试验#1:

$ java A "<----=====><<---<==->>==>" 
<---- 
=====> 
< 
<--- 
<== 
-> 
> 
==> 

执行命令#2:

$ java A "<----=====><=><---<==->>==>" 
<---- 
=====> 
<= 
> 
<--- 
<== 
-> 
> 
==> 

说明

星号将匹配零个或多个前面的字符。加号(+)将匹配一个或多个前面的字符。因此<-*匹配<<-+匹配<-和任何扩展版本(例如<--------)。

0

对于< =======你需要< = +作为正则表达式。 < = *将匹配零个或多个='s,这意味着它将始终匹配零个案例,因此<。对于其他情况也是如此。你应该阅读一些正则表达式。这本书是太棒了: Mastering Regular Expressions

0

您提供的正则表达式字符串做工作,为你的榜样: “< ---- =====> < == - >>”

String p = "<=*|<-*|=*>|-*>"; 
Matcher A = Pattern.compile(p).matcher(s); 
    while (A.find()) { 
      System.out.println(A.group()); 
        } 

然而,在输入字符串“< - ”中产生“<”,但奇怪的是“< =”产生“< =”,因为它应该如此。

5

当您将"<=*|<-*|=*>|-*>"与字符串"<---"相匹配时,它与模式的第一部分"<=*"匹配,因为*包含零个或多个。 Java匹配是贪婪的,但它不够聪明,知道有另一个可能的更长时间匹配,它只是找到匹配的第一个项目。

1

您的第一个解决方案将匹配您正在查找的所有内容,因为您将每个模式一次发送到匹配器中,然后他们有机会单独处理目标字符串。

您的第二次尝试将不会以相同的方式工作,因为您将单个模式与多个表达式放在一起,并且OR'd字符串有优先规则,最先尝试最左侧的标记。如果有匹配,无论多么简单,get()都会返回该匹配并从那里继续。

请参见Thangalin对解决方案的回应,该解决方案将使第二份工作成为第一份工作。