Проблема с заменой регулярных выражений, отрицательный прогноз ведет себя не так, как ожидалось

#regex

#регулярное выражение

Вопрос:

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

 (^http://.*?/)(?!en/|w{2}-w{2}/)(?<path>.*?$)
  

Итак, я хочу сопоставить все до первой косой черты, затем проверить, что языковой стандарт не существует. Локалями могут быть либо ‘en’, либо обычный код локали в стиле ‘en-GB’ на нашем сайте. В настоящее время этот шаблон будет выполнять следующее:

http://www.mywebsite.com/location/index.html => http://www.mywebsite.com/en/location/index.html http://www.mywebsite.com/en/location/index.html => http://www.mywebsite.com/en/en/location/index.html

используя следующий шаблон замены: $ 1en/${path}

Итак, первый работает правильно, но второй соответствует, хотя я этого и не хочу, а затем все равно вставляет код локали.

Это то, что я хочу сделать возможным, звучит так, как должно быть. Заранее спасибо за любую помощь.

Комментарии:

1. Какой язык программирования / диалект регулярных выражений вы используете? .NET?

Ответ №1:

Попробуйте заменить первое .*? на [^/]* .

Например: ^(http://[^/s]*/)(?!en/|w{2}-w{2}/)(?<path>S*)$

Ответ №2:

«я хочу сопоставить все до первой косой черты, затем проверить, что языковой стандарт не существует».

Что это (^http://.*?/)(?!en/|w{2}-w{2}/)(?<path>.*?$) делает, так это сопоставляет все
с первой косой чертой, перед которой нет en .

Это отличается от сопоставления с первой косой чертой, а затем завершается неудачей, если en находится перед ней.

Регулярное выражение всегда будет пытаться выполнить переход по кратчайшему пути. Даже при том, что он действует некорректно, используя ? , на самом деле он будет продолжаться до тех пор, пока не удовлетворит привязке или условию, завершающему его. В этом случае он обнаружил косую черту без en перед ней: www.mywebsite.com/en/ и это не первая косая черта, это вторая.

Это ошибка, это происходит постоянно, и это стоит отметить на будущее.
Таким образом, целью было бы ограничить его соответствие ПЕРВОЙ косой черте: [^/]*/

Комментарии:

1. Спасибо за действительно подробное объяснение по этому поводу, я постараюсь запомнить это на будущее.

Ответ №3:

Вместо этого используйте это регулярное выражение:

 ^(http://[^/] /)(?!en/|w{2}-w{2}/)(?<path>.*)$
  

Комментарии:

1. вы хотели включить ~ на обоих концах, похоже, это не сработает, если вы это сделаете

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

3. Отредактировал свой ответ, чтобы убрать путаницу ~ (который я использовал для своего тестирования).