2014-10-08 2 views
0

Моего код регулярного выражения выглядит следующим образом:Regex периода соответствия все минус последнего символ

(.(?!\[view street map\]))+ 

Это означало, чтобы соответствовать все вплоть до [вида карты улиц].

Но если я использую это регулярное выражение код на следующей

Test of the system[view street map] 

Это соответствует следующему, и отрезает последнего символа

Test of the syste 

Кто-нибудь есть какие-либо идеи, почему это происходит?

Заранее благодарен!

ответ

2

Вы должны делать проверку перед употреблением характера:

^((?!\[view street map\]).)+ 

Потребляйте затем проверьте недопустимую строку также ошибочно соответствует строке «[вид карты улиц]».

Я забыл о закреплении в предыдущей редакции. Нам нужно убедиться, что совпадение начинается с начала строки, или проверка может быть обойдена, когда повторная попытка повторного запуска двигателя соответствует следующему индексу.

+0

Спасибо, что объяснил это, имеет смысл. :) – DanielRHarris

+0

почему ваше регулярное выражение не удается здесь http://regex101.com/r/hQ1rP0/54v? –

+2

Однако, в строке '[view street map]', это теперь будет соответствовать 'view street map]'. –

2

Вам необходимо добавить стартовый якорь, чтобы соответствовать всем до [view street map], если [view street map] присутствует на этой конкретной линии. Если [view street map] нет, это соответствует всей строке.

^(?:(?!\[view street map\]).)+ 

DEMO

Пояснение:

  • ^ Якорь, который обозначает начало строки.
  • (?:..) Вызывается не захватывающей группой.
  • (?:(?!\[view street map\]).) Перед тем, как двигатель регулярного выражения соответствует первому символу, проверьте, соответствует ли строка после границы [view street map]. Если это [view street map], то ничего не будет. Если это не [view street map], то только он соответствует первому символу. Если мы добавим + после целой группы, не связанной с захватом, двигатель regex выполнит вышеописанный шаг для каждого символа с начала (не только для первого символа). + повторяет предыдущий токен один или несколько раз.
+1

Я думаю, вы должны объяснить порядок '(?!) И' .', в дополнение к тому, что у вас есть сейчас, чтобы вы ответите стоять на своем своя. – nhahtdh

+0

@nhahtdh исправьте меня, если я ошибаюсь .. –

0

(.(?!\[view street map\]))+ по существу говорит о совпадении персонажа и проверяет, есть ли [view street map] вперед или нет. m был [view street map] впереди. Так что это не удалось. Все остальное прошло.

Вы можете попробовать:

\[view street map\]|(.) 

захватить захваты и объединить их вместе, чтобы получить строку. См. demo.

Или попробуйте

\[view street map\] 

Замените пустую строку. См. demo.

+0

Проблема с этим подходом заключается в том, что вы получите один символ в группе захвата, и вам нужно объединить их вместе, чтобы получить строку. – nhahtdh

0

Ваша текущая логика - принимать все символы по одному, каждый из которых не следует [view street map]. Вы можете изменить логику на следующую: взять партию символов, затем [view street map] или end-of-string.

.*?(?=(?:\[view street map\])|$) 

Regular expression visualization

Demo

+0

Почему это терпит неудачу здесь http://regex101.com/r/tD6vY9/2? –

+0

@AvinashRaj Пожалуйста, определите 'fail'. Вы используете модификатор 'g', конечно, на' hello [view street map] 'он найдет 4 совпадения. Я намеренно не указывал модификатор 'g', чтобы возвращалось только первое совпадение (требуемое). –

+0

Извините PHP использует глобальный модификатор по умолчанию. –