Regex: поиск совпадений только вне одинарных кавычек

В настоящее время у меня есть регулярное выражение, которое выбирает все вхождения (, , , );:

(\s\()|(,\s)|(\),)|(\);)

однако я пытался найти способ, чтобы, если что-то находится в одинарных кавычках 'like this, for example', оно игнорировало любое из совпадений, перечисленных выше. Я пробовал много разных решений, но ни одно из них мне не помогло.

Кто-нибудь знает, как я мог бы заставить эту работу работать?

Можете ли вы обновить свой вопрос, указав исходные данные и ожидаемые результаты?

user24714692 13.07.2024 06:09

Чтобы добавить к приведенному выше комментарию, какова ваша настоящая цель и что вы пытаетесь сопоставить/извлечь?

Tim Biegeleisen 13.07.2024 07:05

Добавлю обязательно, это не обычный язык, регулярное выражение его не разбирает.

le3th4x0rbot 13.07.2024 12:17

Как в этом формате ввода будут закодированы одинарные кавычки (которые должны быть частью текста)?

trincot 13.07.2024 16:37
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
4
70
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать шаблон типа ('[^']*')|(\s\()|(,\s)|(\),)|(\);) и фильтровать те подстроки, которые вам не нужны.

import re

p = r"('[^']*')|(\s\()|(,\s)|(\),)|(\);)"
s = """'like this, for example' ("""
print([m for match in re.findall(p, s) for m in match if m and not match[0].startswith("'")])

Принты

[' (']


Примечание:

  • ('[^']*') — это та часть, которую вы хотите исключить.
Ответ принят как подходящий

Выражение «не найдено» — непростая задача, поскольку все вокруг регулярного выражения спроектировано так, чтобы работать позитивным/жадным способом (находить как можно больше, когда это возможно).

Самое простое и, вероятно, самое быстрое, что вы можете сделать, — это удалить части, которые вы хотите исключить, перед применением поиска, предполагая, что кавычки всегда появляются парами:

"'[^']*'" => ""

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

Пример Python:

import re

text = "this is a , and this a ( whith a ) while 'this ( is in quotes,therefore excluded' unlike these: ( ) , but 'these () are again'. period."
print(text)
placeholders = []
def repl(m):
    contents = m.group(1)
    placeholders.append(contents)
    return "###Placeholder{0}###".format(len(placeholders) - 1)

temp=re.sub('(\'[^\']*\')', repl, text)
print(temp)

temp=re.sub('([,\)\(])', "`\\1`", temp)
print(temp)
for k in range(len(placeholders)):
  temp = re.sub("###Placeholder{0}###".format(k), placeholders[k], temp)

print(temp)

(Обратите внимание, что ### также гарантирует, что Placeholder1 и Placeholder13 не столкнутся в дальнейшем.)

это a, и это a (с a), в то время как «это (находится в кавычки, поэтому исключены» в отличие от этих: ( ) , но «эти () являются снова'. период.

это a , и это a ( with a ) в то время как ###Placeholder0### в отличие от эти: ( ) , но ###Placeholder1###. период.

это ,, а это ( с ), а ###Placeholder0### в отличие от этих: (), но ###Placeholder1###. период.

это , и это ( с ), пока 'это ( находится в кавычки,поэтому исключены» в отличие от этих: (), но «эти () являются снова'. период.


Или с помощью питонического оператора * последний этап замены re можно было бы пропустить. (Однако это может вызвать проблемы, если {0} и прочее появляются естественным образом):

import re

text = "this is a , and this a ( whith a ) while 'this ( is in quotes,therefore excluded' unlike these: ( ) , but 'these () are again'. period."
print(text)
placeholders = []
def repl(m):
    placeholders.append(m.group(1))
    return "{"+"{0}".format(len(placeholders) - 1) + "}"

temp=re.sub('(\'[^\']+\')', repl, text)
print(temp)

temp=re.sub('([,\)\(])', "`\\1`", temp)
print(temp)

temp = temp.format(*placeholders)
print(temp)

Проблема в том, что вам нужно сопоставить всю строку от начала до конца, чтобы определить, какие одинарные кавычки являются открывающими, а какие — закрывающими. Но попробуйте что-нибудь вроде

re.findall(
    r"(?:(?:'[^']*')[^']*)*(\s\()|(,\s)|(\),)|(\);)",
    text)

который добавляет (?:(?:'[^']*')[^']*)* перед вашим захватывающим выражением лица.

Это будет странно работать для входных данных с непарными одинарными кавычками, но должно работать нормально, если ваши входные данные простые и регулярные (а если нет, то вам, вероятно, все равно нужно что-то более мощное, чем просто регулярные выражения).

Другие вопросы по теме