2016-03-29 31 views
0

我正在從模板生成配置文件。模板看起來像這樣:如何爲給定的情況編寫正則表達式

$Country$$Country$ 
WAN$Country$/$Country$ 
$Country$/29 
$Country$/$Country$ 
"$fdfsrwdrdgf$1$asffdjhk" 

這只是一個示例。我認爲兩個$之間的任何東西都是佔位符。所以在上例中Country是我需要的唯一佔位符。我使用下面的正則表達式中的Java代碼:

{"\\$[^$]*\\$";} 

現在,我的問題是,我不希望引號內任何與上述RE的認可,或者說我想改變RE等它會忽略引號內的內容("")。任何人都可以幫我一下嗎?

+2

['(? 「[^」] +「)|(? \ $ [^ $] * \ $)'](https://regex101.com/r/xE7wA4/1) –

回答

3

可以使用Best Trick Ever

你還記得我們試圖匹配泰山的所有實例除雙引號括起來的簡單情況......嗯,你現在看到的是多麼簡單的

"Tarzan"|(Tarzan)

真的:當你用最好的正則表達式的伎倆永遠成爲問題?而已?

是的。訣竅是,我們匹配我們不希望在變化|),左側的,然後我們捕獲我們想要在右側我們想要的。當我們的編程語言返回結果時,我們忽略整體匹配(這是垃圾桶),而是將我們的全部注意力轉向包含我們之後的組1匹配。

因此,所有你需要的是

"[^"]+"|(\$[^$]*\$) 

或者(如果你有轉義序列:

"[^"\\]*(?:\\.[^\\"]*)*"|(\$[^$]*\$) 

,並獲得捕獲組#1的內容,請參閱regex demo

Demo

String s = "$Country$$Country$\nWAN$Country$/$Country$\n$Country$/29\n$Country$/$Country$\n\"$fdfsrwdrdgf$1$asffdjhk\""; 
Pattern pattern = Pattern.compile("\"[^\"\\\\]*(?:\\\\.[^\\\\\"]*)*\"|(\\$[^$]*\\$)"); 
Matcher matcher = pattern.matcher(s); 
List<String> res = new ArrayList<>(); 
while (matcher.find()){ 
    if (matcher.group(1) != null) { 
     res.add(matcher.group(1)); 
     //     ^- Get Group 1 only! 
    } 
} 
System.out.println(res); 
// => [$Country$, $Country$, $Country$, $Country$, $Country$, $Country$, $Country$] 
+0

這個技巧就像是魔法! – Quinn

+1

謝謝so多爲這樣一個詳細的解釋!它的工作! – sahana