2015-01-15 4 views
1

Я видел другие подобные вопросы, но все они были связаны с совпадением в начале в конце, и это не то, что я ищу.Regex - Соответствие шаблону, не содержащему строку

Я хочу, чтобы соответствовать параметрам с синтаксисом:

{{param-name}} или {{param-name=default value}}

До сих пор у меня есть следующее регулярное выражение:

(\{\{[a-zA-Z0-9_-]*(?:=.*)?\}\}) 

Но проблема в том, что если есть более один параметр, он создает только одно совпадение: от начала первого до конца последнего. Например:

bla bla {{foo=blabla}} bla bla {{bar=hehe}} bla bla 

будет соответствовать: {{foo}} bla bla {{bar=hehe}} в то время как я хочу {{foo}} и {{bar=hehe}}

Поэтому мне нужно проверить, что после = характера, нет }} строки перед }} завершения параметра.

Я не знаю, как это сделать. Вы можете мне помочь ? Спасибо :)

PS: Я использую это на Java, если это имеет значение.

ответ

6

Сделать .* после = как не жадный.

(\{\{[a-zA-Z0-9_-]*(?:=.*?)?\}\}) 

DEMO

Java регулярное выражение будет,

"(\\{\\{[a-zA-Z0-9_-]*(?:=.*?)?\\}\\})" 

ИЛИ

(\{\{[a-zA-Z0-9_-]*(?:=(?:(?!}}).)*)?\}\}) 

DEMO

В этом случае я модифицировал .*? внутри необязательной группы, не связанной с захватом, с помощью (?:(?!}}).)*.

  • (?!..) называется отрицательное утверждение. Это не соответствует ни одному символу, но утверждает, что совпадение будет происходить в определенном месте или нет. Здесь (?!}}). Проверяет, что символ, который мы собираемся совместить, не будет }}. То есть следующий символ не будет первым закрывающим фигурным скобком в }}

  • Если да, то будет соответствовать только соответствующий символ.

  • Значит, это (?:(?!}}).)* Соответствует любому символу, но не }} ноль или более раз. ? рядом с * забрасывает *, чтобы совершить не-жадный матч. Обратите внимание, что это будет соответствовать одной закрывающей фигурной скобке.

Код:

String s = "bla bla {{foo}} bla bla {{bar=hehe}} bla bla"; 
Matcher m = Pattern.compile("\\{\\{[a-zA-Z0-9_-]*(?:=(?:(?!}}).)*)?\\}\\}").matcher(s); 
while(m.find()) 
{ 
    System.out.println(m.group()); 
} 

Выход:

{{foo}} 
{{bar=hehe}} 
+0

Благодаря это работает. Не могли бы вы объяснить мне второй вариант? Я видел вещи о!! но я их не понимал. Спасибо. – Virus721

+0

Я думаю, теперь будет ясно. –

+0

Да, его ясное спасибо, но я понимаю, что это проблема. Только первый параметр сопоставляется, как вы можете видеть здесь: 'https: // www.regex101.com/r/aQ4mF3/1'. Почему второй не подходит? – Virus721

-1

В Java Обычно все регулярные выражения работают отлично, но изменения синтаксиса. Использование Double slash ('\') вместо одиночного.

Попробуйте:

(\\{\\{[A-Za-z0-9_-]*(?:=.*)?\\}\\}) 
Смежные вопросы