Найти все вхождения нескольких условий регулярного выражения, используя регулярное выражение Python - PullRequest
0 голосов
/ 26 сентября 2019

Учитывая 2 различных шаблона регулярных выражений, я хочу найти все вхождения этих 2 шаблонов.Если соответствует только шаблон 1, верните его, если соответствует только шаблон 2, затем верните его, а если шаблон 1 и шаблон 2 совпадут, верните оба из них.Итак, как мне запустить несколько (в данном случае 2 регулярных выражений) в одном операторе?

Заданная строка ввода:

"https://test.com/change-password?secret=12345;email=test@gmail.com;previous_password=hello;new=1"

Я хочу получить значение только электронной почты и секрета.Поэтому я хочу вывод как ['12345', 'test@gmail.com']

import re
print(re.search(r"(?<=secret=)[^;]+", s).group())
print(re.search(r"(?<=email=)[^;]+", s).group())

Я могу получить ожидаемый результат, запустив регулярное выражение несколько раз.Как мне достичь этого за одно утверждение?Я не хочу запускать re.search 2 раза.Могу ли я достичь этого в одном поисковом запросе?

Ответы [ 4 ]

2 голосов
/ 26 сентября 2019
>>> re.findall(r"((?:(?<=email=)|(?<=secret=))[^;]+)", s)
['12345', 'test@gmail.com']

Но теперь вам понадобится способ определить, какое из полученных значений является секретом, а какое - электронным письмом.Я бы порекомендовал также извлечь эту информацию с помощью регулярного выражения (что также исключает обзор):

>>> dict(kv.split('=') for kv in re.findall(r"((?:secret|email)=[^;]+)", s))
{'secret': '12345', 'email': 'test@gmail.com'}
1 голос
/ 26 сентября 2019

Вы можете использовать разборчивое понимание:

import re
url = "https://test.com/change-password?secret=12345;email=test@gmail.com;previous_password=hello;new=1"

rx = re.compile(r'(?P<key>\w+)=(?P<value>[^;]+)')

dict_ = {m['key']: m['value'] for m in rx.finditer(url)}

# ... then afterwards ...
lst_ = [value for key in ("secret", "email") if key in dict_ for value in [dict_[key]]]
print(lst_)
# ['12345', 'test@gmail.com']
1 голос
/ 26 сентября 2019
import re

print(re.findall("(?<=secret=)[^;]+|(?<=email=)[^;]+", s))

# output
# ['12345', 'test@gmail.com']
0 голосов
/ 28 сентября 2019

Итак, я использовал urllib, как предложено @ ctwheels

url_exclude = ["email", "secret"]
import urllib.parse as urlparse
from urllib.parse import urlencode, urlunparse
url_parsed_string = urlparse.urlparse(input_string)
parsed_columns = urlparse.parse_qs(url_parsed_string.query)
for exclude_column in url_exclude:
    if exclude_column in parsed_columns:
        parsed_columns[exclude_column] = "xxxxxxxxxx"
qstr = urlencode(parsed_columns)
base_url = urlunparse((url_parsed_string.scheme, url_parsed_string.netloc, 
url_parsed_string.path, url_parsed_string.params, qstr, 
url_parsed_string.fragment))
print(base_url)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...