2009-07-25 60 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對解決方案的迴應,該解決方案將使第二份工作成爲第一份工作。