2016-03-29 4 views
0

Я работаю над созданием файла конфигурации из шаблона. Шаблон выглядит примерно так:Как написать регулярное выражение для данной ситуации

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

Это всего лишь образец. Я считаю что-то между двумя $ s в качестве заполнителя. Поэтому в приведенном выше примере 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

Спасибо, много Для такого подробного объяснения! Это работает! – sahana

Смежные вопросы