Использование регулярных выражений для создания списка словарей с положительным внешним видом

#python #regex #dictionary #positive-lookbehind

#python #регулярное выражение #словарь #положительный внешний вид

Вопрос:

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

Вариант 1

 string = '146.204.224.152 - lubo233'

for item in re.finditer( "(?P<host>[0-9]*[.][0-9]*[.][0-9]*[.][0-9]*)(?P<user_name>(?<= - )[a-z]*[0-9]*)", string ):
    print(item.groupdict())
 

Вариант 2

 string = '146.204.224.152 - lubo233'
for item in re.finditer( "(?P<host>[0-9]*[.][0-9]*[.][0-9]*[.][0-9]*)(?<= - )(?P<user_name>[a-z]*[0-9]*)", string ):
    print(item.groupdict())
 

Желаемый результат

 {'host': '146.204.224.152', 'user_name': 'lubo233'}
 

Вопрос / проблема

В обоих случаях я не могу удалить подстроку » — «.

Использование положительного внешнего вида (?<= - ) делает мой код неправильным.

Кто-нибудь может помочь определить мою ошибку? Спасибо.

Ответ №1:

Я бы посоветовал вам удалить положительный внешний вид и просто нормально поместить символ соединения между каждой частью

Также некоторые улучшения

  • . вместо [.]
  • [0-9]{,3} вместо [0-9]*
  • (?:.[0-9]{,3}){3} вместо .[0-9]{,3}.[0-9]{,3}.[0-9]{,3}

Добавьте a .* вместе с - для обработки любого слова, которое может быть там

 rgx = re.compile(r"(?P<host>[0-9]{,3}(?:.[0-9]{,3}){3}).* - (?P<user_name>[a-z]*[0-9]*)")

vals = ['146.204.224.152 aw0123 abc - lubo233',
        '146.204.224.152 as003443af - lubo233',
        '146.204.224.152 - lubo233']

for val in vals:
    for item in rgx.finditer(val):
        print(item.groupdict())

# Gives
{'host': '146.204.224.152', 'user_name': 'lubo233'}
{'host': '146.204.224.152', 'user_name': 'lubo233'}
{'host': '146.204.224.152', 'user_name': 'lubo233'}
 

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

1. Я понимаю, что вы имеете в виду. Но что происходит, когда между двумя подстроками есть неизвестная длина символов: ‘146.204.224.152’ и ‘ — lubo233’? Пример: string = ‘146.204.224.152 aw0123 abc — lubo233’ или string = ‘146.204.224.152 as003443af — lubo233’

2. @KaneChew Пожалуйста, отредактируйте свой первоначальный пост, чтобы добавить несколько примеров входной строки. Кроме того, мой код делает то же самое, что и ваш, и его работа, ваш исходный код НЕ обрабатывал возможное различное содержимое в середине 😉

Ответ №2:

Причина, по которой положительный внешний вид не работает, заключается в том, что вы пытаетесь сопоставить:

  • (?P<host>[0-9]*[.][0-9]*[.][0-9]*[.][0-9]*) IP-адрес
  • сразу же следует шаблон имени пользователя: (?P<user_name>(?<= - )[a-z]*[0-9]*) ему должно предшествовать (?<= - )

Итак, как только механизм регулярных выражений использует шаблон IP-адреса, который вы указываете, который должен соответствовать шаблону имени пользователя, которому предшествует, (?<= - ) но предшествует шаблон IP-адреса. Другими словами, после сопоставления шаблона IP остается строка:

 - lubo233
 

Шаблон, который должен быть немедленно сопоставлен, как в re.match, является:

 (?P<user_name>(?<= - )[a-z]*[0-9]*) 
 

это, очевидно, не соответствует. Чтобы проиллюстрировать мою точку зрения, посмотрите, что этот шаблон работает:

 import re

string = '146.204.224.152 - lubo233'
for item in re.finditer(r"((?P<host>[0-9]*[.][0-9]*[.][0-9]*[.][0-9]*)( - ))(?P<user_name>(?<= - )[a-z]*[0-9]*)", string):
    print(item.groupdict())
 

Вывод

 {'host': '146.204.224.152', 'user_name': 'lubo233'}
 

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

 import re

string = '146.204.224.152 adfadfa - lubo233'
for item in re.finditer(r"((?P<host>d{3,}[.]d{3,}[.]d{3,})(.* - ))(?P<user_name>(?<= - )[a-z]*[0-9]*)", string):
    print(item.groupdict())
 

Вывод

 {'host': '146.204.224', 'user_name': 'lubo233'}
 

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

1. Следуя вашему ходу мыслей, «как только механизм регулярных выражений использует шаблон IP-адреса», остается следующая подстрока: » — lubo233″. В этом случае перед именем пользователя не стоит » -«? Или я неправильно понимаю регулярное выражение?

2. @KaneChew положительный внешний вид не использует строку. Как вы сказали, оставшаяся строка — » — lubo233″, и вы говорите ей, что ей должно предшествовать » — «.