2016-04-27 5 views
1

У меня есть регулярное выражение, которое кажется простым, но не действует как требуется. Вход должны быть проанализирован описываются следующим образом (NB: {} не является частью регулярного выражения, только то, что внутри):RE2 (Rust) регулярное выражение не работает должным образом

  • Последовательность 0 или более пространств {\ S *}
  • тира { -}
  • Последовательность 0 или более пробелов {\ s *}
  • Полное имя человека (имя, отчество, фамилия, фамилия, все помеченные в f1). Имя не должно начинаться с цифры должен появиться в конце строки {[A-Za-Z] [\ W \ с] *)}

вся конструкция ПРОСТРАНСТВО-SPACEf1 является необязательным

Просто, чтобы объяснить, что записано в f1: Для первого символа я использую набор символов, представленных [A-Za-z]. За ним следует \ w или пробел 0 или более раз. Это фиксируется в f1.

(?:\s*-\s*(?P<f1>[A-Za-z][\w\s]*))?$ 

Я ожидаю, что следующие последовательности, чтобы соответствовать и захватить значение в f1:

  • "- Брюс" (f1 = Bruce)
  • "- Брюс Дикинсон" (f1 = Bruce Dickinson)

Я ожидаю, что следующее не совпадает:

  • «Брюс» (нет ведущей тире)
  • «- Брюс!» (Есть не слово (\ ш) характер после того, как имя и до конца строки

Я ожидаю, что следующий матч, но не захватить значение в f1 (я бы предпочел, чтобы не совпадать, хотя):

  • "- 1Bruce" (ведущий символ числовой)

Эти фактические результаты:

  • "- Брюс" (f1 = Bruce) Tick; это работает
  • "- Брюс Дикинсон" (f1 = Брюс Дикинсон) Тик; это работает

  • «Брюс» (f1 = не учитываются, но выражение матч. Это неправильно, потому что Брюс не соответствует дополнительной части, а $ приходит следующий, который не соответствует Bruce)

  • "- Брюс!" (f1 = не cpatured, но выражение является совпадением, это неверно, из-за!, что означает, что совпадение не отображается в конце строки.

Я ожидаю, что:

(?:\s*-\s*(?P<f1>[A-Za-z][\w\s]*))? 

будет потреблять {- Bruce}, который должен уйти, который должен потерпеть неудачу из следующего регулярного выражения двоеточие $; Однако, компьютер говорит, что нет, так что я не прав, но я не знаю, почему :(

  • «- 1Bruce». (f1 = не учитываются, но выражение матча Это вполне понятно, поскольку в целом {пространства dash space f1} является необязательной и потому что она не соответствует, эта конструкция пропускается, а затем на входе ничего не обрабатывать, мы попадаем в конец строки)

Если я могу получить это, работа, я могу заставить остальную часть своего выражения работать так, как я этого хочу. Мне нужно, чтобы кто-то другой заставлял меня думать об этом по-другому. Я потратил на это 2 дня без положительного результата, так что очень расстраиваю.

PS: Я использую regex101.com для проверки регулярных выражений. Регулярные выражения будут использоваться как часть приложения Rust, чей механизм regex основан на RE2 Google.

В конце концов, мне нужно уметь распознавать последовательность имен, разделенных &, а все выражение является необязательным с использованием? и должен появиться в конце строки $.

Так

  • {- Брюс & Nicko & Dave Murray} будет действительным

и

  • {- Брюс & Nicko & Дэйв Мюррей &} не должен быть действительным и НЕ соответствует

Но 1 шаг за раз!

+0

Было бы хорошо, если бы вы включили фактический код, который мы можем запустить для тестирования. – Dogbert

+0

У меня нет кода. Я тестирую его в regex101.com.Когда я получу эту работу, я переверну ее в код, но это легкая часть. – Zephilim

+0

Если это помогает, я могу написать единичный тест и опубликовать, если это лучше? – Zephilim

ответ

3

Дело в том, что вы не можете совместить и не совпадать с чем-то одновременно. Если вы сделаете весь шаблон необязательным, а конец строки обязательным, даже если нет ничего интересного, конец строки будет согласован - всегда.

Выход из этого соображения состоит в том, чтобы думать о подшаблоне, в котором вы заинтересованы. Вас интересуют имена, поэтому сделайте первую букву обязательной. Дефис кажется обязательным во всех тестовых случаях, которые вы поставили. Все остальное может быть дополнительно:

\s*-\s*(?P<f1>([^\W\d_])\w*(?:\s+\w+)*)(?:\s*&\s*(?P<f2>([^\W\d_])\w*(?:\s+\w+‌​)*))*$ 

Смотрите regex demo (\s заменяется \h и \n добавленным к отрицаний классов символов только для демонстрационных целей, как это многострочный демо).

Обратите внимание, что я заменил [a-zA-Z] на [^\W\d_], чтобы сделать рисунок более гибким ([^\W\d_] соответствует любой букве).

+1

Огромное спасибо Wiktor – Zephilim

+0

Рад помочь. Когда вы пишете шаблоны регулярных выражений, попробуйте * be * двигатель регулярных выражений: сначала следуйте линейной логике: сравните это, зафиксируйте это, не соответствуйте этому ... до ... end. Текущий шаблон выглядит ужасно (возможно, он есть), но он довольно линейный и эффективный. Короткие рисунки не всегда оказываются наиболее эффективными, BTW. –

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