#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″, и вы говорите ей, что ей должно предшествовать » — «.