2011-02-15 101 views
0

我想搜索字符串以查找與特定模式匹配的字符串。 然後,我將編寫由逗號分隔的唯一發現字符串列表。 該模式是尋找"$FOR_something"只要該模式不落在"#LOOKING()""/* */"和_something部分沒有任何其他特殊字符。如何識別字符串中的字符串模式,但忽略匹配是否落入已識別模式

舉例來說,如果我有這樣的字符串,

"Not #LOOKING($FOR_one $FOR_two) /* $FOR_three */ not $$$FOR_four or $FOR_four_b, but $FOR_five; and $FOR_six and not $FOR-seven or $FOR_five again" 

中發現的模式我正在尋找從以上引用的字符串會的結果列表:

$FOR_five, $FOR_six 

我開始用這個例如:

import java.lang.StringBuffer; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
public class testIt { 
public static void main(String args[]) { 

String myWords = "Not #LOOKING($FOR_one $FOR_two) /* $FOR_three */ not $$$FOR_four or $FOR_four_b, but $FOR_five; and $FOR_six and not $FOR-seven or $FOR_five again"; 

StringBuffer sb = new StringBuffer(0); 

if (myWords.toUpperCase().contains("$FOR")) 
{ 
    Pattern p = Pattern.compile("\\$FOR[\\_][a-zA-Z_0-9]+[\\s]*", Pattern.CASE_INSENSITIVE); 
    Matcher m = p.matcher(myWords); 

    String myFors = ""; 
    while (m.find()) 
    { 
     myFors = myWords.substring(m.start() , m.end()).trim(); 
     if (sb.length() == 0) sb = sb.append(myFors); 
     else 
     { 
     if (!(sb.toString().contains(myFors))) sb = sb.append(", " + myFors); 
     } 
    } 
} 
System.out.println(sb); 
} 

} 

但它沒有給我我想要的。我想要的是:

$FOR_five, $FOR_six 

相反,我得到所有的$ FOR_somethings。我不知道如何忽略/**/#LOOKING()中的發生。 有什麼建議嗎?

回答

0

這個問題超出了常規的正則表達式我會說。 $$$模式可以固定負面看後面,其他人不會那麼容易。

我建議您首先使用標記化/手動字符串解析來丟棄不需要的數據,例如/* ... */#LOOKING(....)。這可能不過也是另一個正則表達式除去,例如:

myWords.replaceAll("/\\*[^*/]+\\*/", "");  // removes /* ... */ 
myWords.replaceAll("#LOOKING\\([^)]+\\)", ""); // removes #LOOKING(...) 

一旦脫去你可以使用e..g,下面的正則表達式的基於上下文的內容:

(?<!\\$)\\$FOR_\\p{Alnum}+(?=[\\s;]) 

說明:

(?<!\\$)   // Match iff not prefixed with $ 
\\$FOR_   // Matches $FOR_ 
\\p{Alnum}+  // Matches one or more alphanumericals [a-zA-Z0-9] 
(?=[\\s;])  // Match iff followed by space or ';' 

請注意,被僱用的(?...)被稱爲先行/後視表達式,它們在結果本身中未被捕獲。它們只作爲上述示例中的前綴/後綴條件。