Замените шаблоны, которые находятся внутри разделителей, используя вызов регулярного выражения - PullRequest
2 голосов
/ 08 октября 2008

Мне нужно вырезать все вхождения шаблона '-', которые находятся внутри одинарных кавычек в длинной строке (оставляя без изменений те, которые находятся вне одинарных кавычек).

Есть ли способ регулярного выражения сделать это? (использование с итератором из языка в порядке).

Например, начиная с

"xxxx rt / $ 'dfdf--fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '--ggh--' vcbcvb"

Я должен закончить с:

"xxxx rt / $ 'dfdffggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g 'ggh' vcbcvb"

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

  • JavaScript input.replace (/ someregex / g, "")
  • PHP preg_replace ('/ someregex /', "", input)
  • Python re.sub (r'someregex ', "", input)
  • Ruby input.gsub (/ someregex /, "")

Ответы [ 5 ]

2 голосов
/ 08 октября 2008

Я нашел другой способ сделать это из ответа Грега Хьюгилла при Qn138522
Он основан на использовании этого регулярного выражения (адаптированного к шаблону, который я искал):

--(?=[^\']*'([^']|'[^']*')*$)

Грег объясняет:

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

Примеры использования:

  • JavaScript: input.replace(/--(?=[^']*'([^']|'[^']*')*$)/g, "")
  • PHP: preg_replace('/--(?=[^\']*'([^']|'[^']*')*$)/', "", input)
  • Python: re.sub(r'--(?=[^\']*'([^']|'[^']*')*$)', "", input)
  • Рубин: input.gsub(/--(?=[^\']*'([^']|'[^']*')*$)/, "")

Я проверил это на Ruby, и он дает желаемый результат.

2 голосов
/ 08 октября 2008

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

Лучше всего перебирать строковые символы за символом, сохраняя логический флаг, независимо от того, находитесь ли вы в указанном регионе или нет, и удалять - таким образом.

1 голос
/ 08 октября 2008

Если немного изменить правила, это может сработать:

import re
p = re.compile(r"((?:^[^']*')?[^']*?(?:'[^']*'[^']*?)*?)(-{2,})")
txt = "xxxx rt / $ 'dfdf--fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '--ggh--' vcbcvb"
print re.sub(p, r'\1-', txt)

Выход:

xxxx rt / $ 'dfdf-fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '-ggh-' vcbcvb

Регулярное выражение:

(               # Group 1
  (?:^[^']*')?  # Start of string, up till the first single quote
  [^']*?        # Inside the single quotes, as few characters as possible
  (?:
    '[^']*'     # No double dashes inside theses single quotes, jump to the next.
    [^']*?
  )*?           # as few as possible
)
(-{2,})         # The dashes themselves (Group 2)

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

-{2,}(?=[^'`]*`)

Редактировать: Я понял, что если строка не содержит кавычек, она будет соответствовать всем двойным тире в строке. Один из способов исправить это было бы изменить

(?:^[^']*')?

в начале

(?:^[^']*'|(?!^))

Обновлено регулярное выражение:

((?:^[^']*'|(?!^))[^']*?(?:'[^']*'[^']*?)*?)(-{2,})
0 голосов
/ 08 октября 2008

Вы можете использовать следующий скрипт sed:

:again
s/'\(.*\)--\(.*\)'/'\1\2'/g
t again

Сохраните это в файле (rmdashdash.sed) и примените любую магию exec на вашем языке сценариев, чтобы вы могли сделать следующий эквивалент оболочки:

sed -f rmdotdot.sed <<em> файл, содержащий ваши входные данные

Что делает скрипт:

:again <- просто этикетка </p>

s/'\(.*\)--\(.*\)'/'\1\2'/g

замените для шаблона «за которым следует все, за чем следует - за которым следует что-то, за которым следует», - только два значения в кавычках.

t again <- вернуть полученную строку обратно в sed. </p>

Обратите внимание, что этот скрипт преобразует «----» в «», поскольку он представляет собой последовательность из двух в кавычках. Однако «---» будет преобразовано в «-».

Не школа, как старая школа.

0 голосов
/ 08 октября 2008

Hm. может быть в Python, если нет апострофов в кавычках, учитывая, что существует (?( id / name ) yes-pattern | no-pattern ) в регулярных выражениях, но в настоящее время это идет мне на ум.

Помогает ли это?

def remove_double_dashes_in_apostrophes(text):
    return "'".join(
    part.replace("--", "") if (ix&1) else part
    for ix, part in enumerate(text.split("'")))

Кажется, работает на меня. Что он делает, разбивает входной текст на части на апострофах и заменяет «-» только тогда, когда часть имеет нечетный номер (т. Е. Перед ней было нечетное количество апострофов). Примечание о "нечетной нумерации": нумерация деталей начинается с нуля!

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