2011-02-15 63 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 ';' 

请注意,被雇用的(?...)被称为先行/后视表达式,它们在结果本身中未被捕获。它们只作为上述示例中的前缀/后缀条件。