Есть ли стандартный способ работы с регулярными выражениями, когда префикс присутствует для нескольких экземпляров? - PullRequest
0 голосов
/ 04 марта 2020

Например:

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

Как заменить префикс ("вещи, которые я хочу") на "вещи, которые я хочу"?

Ответы [ 3 ]

1 голос
/ 04 марта 2020

Используйте lookarounds. Регулярное выражение для этого будет:

regex = r'(?<=prefix\()".*"(?=\))'
re.findall(regex, your_string)

Демо https://regex101.com/r/0ZEXnN/2/

1 голос
/ 04 марта 2020

с использованием группировки

Вопрос был обновлен, чтобы быть более конкретным c после того, как я собрал то, что находится ниже - для более подробного c ответа вы можете прокрутите вниз до ссылки на группы , где у меня есть примеры того, как выполнять замены.

Использование групп для выделения соответствующего текста в целевой строке:

>>> re.findall(r"prefix\((.*?)\)", 'prefix("hello")')[0]
'"hello"'

или, вообще говоря, чтобы взять что-нибудь в скобках:

re.findall(r"\((.*?)\)", 'prefix("hello")')[0]
'"hello"'

демо

>>> target = """
... x = 'prefix("hello"),'
... y = 'prefix("hi"),'
... z = 'prefix("hey"),'
... """
>>> 
>>> re.findall(r"prefix\((.*?)\)", target)
['"hello"', '"hi"', '"hey"']
>>> 

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

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

ссылка https://docs.python.org/3/library/re.html

(... ) Соответствует любому регулярному выражению, заключенному в скобки, и указывает начало и конец группы; содержимое группы может быть получено после сопоставления и может быть сопоставлено позже в строке с помощью специальной последовательности \ number, описанной ниже. Чтобы сопоставить литералы '(' или ')', используйте (или) или заключите их в класс символов: [(], [)].

ссылки на группы

Кроме того, вы можете ссылаться на свои совпадающие группы, используя обратную косую черту sh, и число: \1 будет первой группой совпадений. Это полезно для таких операций, как re.sub()

>>> print(re.sub(r"prefix\((.*?)\)", r"prefix(   && \1 &&   )", target))

x = 'prefix(   && "hello" &&   ),'
y = 'prefix(   && "hi" &&   ),'
z = 'prefix(   && "hey" &&   ),'

>>> 

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

Более по линиям Отвечая на точный вопрос, мы можем извлечь нужный нам текст и отказаться от «префикса» и другого ненужного нам текста:

>>> print(re.sub(r"'prefix\((.*?)\),'", r"\1", target))

x = "hello"
y = "hi"
z = "hey"

>>> 

(при условии, что вы хотите сохранить двойные кавычки в выводе, и теряйте галочки, кавычки и запятые)

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

положительное предпросмотр / утверждение вперед

В большинстве случаев заглядывание вперед / назад не требуется, но они также являются опцией. Они предлагают способ указать предыдущий / последующий текст без группировки. Как и в других сообщениях на вопрос, синтаксис (?<=...) для просмотра назад и (?=...) для просмотра вперед.

Эти подвыражения могут усложнить общее выражение и затруднить его чтение. Может быть, не всегда, но, по моему мнению, их следует использовать с осторожностью.

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

Вот пример, использующий утверждения типа «назад / позади», который делает то же самое, что и в предыдущем примере. Что легче понять - вы можете решить:

>>> print(re.sub(r"(?<=prefix\()(.*?)(?=\))", r"   && \1 &&   ", target))

x = 'prefix(   && "hello" &&   ),'
y = 'prefix(   && "hi" &&   ),'
z = 'prefix(   && "hey" &&   ),'

В конкретном случае вопроса использование этих утверждений приведет к потере текста prefix... из совпадения, и вы не сможете удалить его с выхода re.sub(). Так что в этом случае они не будут работать.

0 голосов
/ 04 марта 2020

Это регулярное выражение работает

x = 'prefix("hello")'
y = 'prefix("hi")'
z = 'prefix("hey")'

import re
for test in (x,y,z):
    print(test, re.match(r".*?\(([^\)]*)", test).group(1))

результат

prefix("hello") "hello"
prefix("hi") "hi"
prefix("hey") "hey"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...