2016-09-30 4 views
1

Я пытаюсь написать регулярное выражение (в Python) для соответствия вводам от пользователя. Я пытаюсь захватить «имя» и «число» со входа.Написание регулярного выражения для соответствия входящему чату

Текущий Regex:

^(?P<start_number>\d+){0,1} (?P<name>.+)|^(?P<name2>.+?)(?:\s+){0,1}(?P<end_number>\d+){0,1}$ 

Входы:

  1. Foo 1
  2. Foo 2 не захватить этот текст
  3. 3 Foo
  4. 4 Foo захвата этот текст
  5. foo 1 2 3

То, что я хочу, чтобы захватить:

  1. Имя: Foo, Num: 1
  2. Имя: Foo, Num: 2
  3. Имя: Foo, Num: 3
  4. Имя: Foo захватить этот текст, Num: 4
  5. имя: Foo, кол-во: 1

Моя проблема заключается в том, что из-за "$" это OBV но если я удалю «$», он только фиксирует первую букву строки для 1,2,5

Любые идеи?Я использую regex101, чтобы помочь мне

Благодаря

+1

Try [ '^ (? :(P \ D +) | (? P . *?)? (? P \ d +). *) $ '] (Https://regex101.com/r/8pfVZR/1) –

ответ

0

Я предлагаю:

^(?:(?P<start_number>\d+) (?P<name>.+)|(?P<name2>.*?) ?(?P<end_number>\d+).*)$ 

Смотрите regex demo

Детали:

  • ^ - начало строки
  • (?:(?P<start_number>\d+) (?P<name>.+)|(?P<name2>.*?) ?(?P<end_number>\d+).*) - не-захвата группы соответствия 1 из 2 альтернатив
    • (?P<start_number>\d+) (?P<name>.+) - 1+ цифры (группа «START_NUMBER»), пространство (может быть заменен \s+) и любые другие 1+, чем LineBreak последовательности символов захватили в группу «имя»
    • | - или
    • (?P<name2>.*?) ?(?P<end_number>\d+).* - любые 0+, кроме LineBreak символов, захваченных в группу «имя2» символы, дополнительное пространство (кажется, что вы можете использовать \s* здесь, тоже), а затем 1+ цифры захвачен в группу «end_number», а затем любые символы 0+ до остальной части строки
  • $ - конец строки

An online test: (?. P +)

import re 
s = ['foo 1', 
"foo 2 don't capture this text", 
'3 foo', 
'4 foo capture this text', 
'foo 1 2 3'] 
pat = r'^(?:(?P<start_number>\d+) (?P<name>.+)|(?P<name2>.*?) ?(?P<end_number>\d+).*)$' 
for x in s: 
    m = re.search(pat, x) 
    if m and m.group("start_number"): 
     print("{0}, {1}".format(m.group("start_number"), m.group("name"))) 
    elif m and m.group("end_number"): 
     print("{0}, {1}".format(m.group("end_number"), m.group("name2"))) 
+0

Я испортил и забыл упомянуть, что иногда число даже нет. E.G действительный вход «foo», и мне нужно зафиксировать это как имя. Этот ответ работает на мой первоначальный вопрос, теперь я пытаюсь отредактировать его, чтобы он соответствовал «foo» «foo bar» и т. Д. – Woody

+0

Возможно, добавьте еще одну альтернативу: ['^ (? :(? P \ d +) (? P . +) | (? P . *?)? (? P \ d +). *? | (? P . *)) $ '] (Https://regex101.com/r/ 8pfVZR/2) –

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