Python, RegEx, заменить определенную часть матча - PullRequest
3 голосов
/ 21 января 2020

Я пытаюсь заменить определенную часть совпадения, найденное регулярным выражением. Соответствующие строки имеют следующий формат:

"<Random text>[Text1;Text2;....;TextN]<Random text>"

Таким образом, в основном может быть N текстов, разделенных символом ";" внутри скобок. Моя цель - поменять ";" в «,» (но только для строк в этом формате), чтобы я мог оставить «;» в качестве разделителя для файла CSV. Таким образом, результат должен быть:

"<Random text>[Text1,Text2,...,TextN]<Random text>"

Я могу сопоставить соответствующие строки с чем-то вроде

re.compile(r'\[".*?((;).*?){1,4}"\]')

, но если я попытаюсь использовать метод sub, он заменит всю строку.

Я искал stackoverflow, и я почти уверен, что "группы захвата" могут быть решением, но я на самом деле не получаю. Кто-нибудь может мне помочь?

Я ТОЛЬКО хочу поменять ";" в ["Text1; ...; TextN"] - части моего текстового файла.

Ответы [ 3 ]

5 голосов
/ 21 января 2020

Попробуйте это регулярное выражение:

;(?=(?:(?!\[).)*])

Замените каждый матч на ,

Нажмите для демонстрации

Объяснение:

  • ; - соответствует ;
  • (?=(?:(?!\[).)*]) - гарантирует, что за вышеуказанным ; следует закрытие ] где-то позже в строке, но перед открывающей скобкой [
    • (?=....) - положительный прогноз
    • (?:(?!\[).)* - 0+ вхождений любого символа, который не начинается с [
    • ] - соответствует ]
1 голос
/ 21 января 2020

Если вы хотите сопоставить ; перед закрытием ] и не сопоставлять [ между ними, вы можете использовать:

;(?=[^[]*])
  • ; Совпадение буквально
  • (?= Позитивный взгляд, утверждают, что справа -
    • [^[]* Класс отрицательных символов, соответствует 0+ раз любому символу, кроме [
  • ] Совпадение буквально
  • ) Закрыть взгляд вперед

Regex demo

Обратите внимание, что это также будет соответствовать, если нет ведущий [


Если вы также хотите убедиться, что есть ведущий [, вы можете использовать модуль PyPi regex и использовать \G и \K для сопоставления с одним ;

(?:\[(?=[^[\]]*])|\G(?!^))[^;[\]]*\K;

Regex demo | Python демо

import regex

pattern = r"(?:\[(?=[^[\]]*])|\G(?!^))[^;[\]]*\K;"
test_str = ("[\"Text1;Text2;....;TextN\"];asjkdjksd;ajksdjksad[\"Text1;Text2;....;TextN\"]\n\n"
    ".[\"Text1;Text2\"]...long text...[\"Text1;Text2;Text3\"]....long text...[\"Text1;...;TextN\"]...long text...\n\n"
    "I ONLY want to change the \";\" in the [\"Text1;...;TextN\"]")

result = regex.sub(pattern, ",", test_str)
print (result)

Выход

["Text1,Text2,....,TextN"];asjkdjksd;ajksdjksad["Text1,Text2,....,TextN"]

.["Text1,Text2"]...long text...["Text1,Text2,Text3"]....long text...["Text1,...,TextN"]...long text...

I ONLY want to change the ";" in the ["Text1,...,TextN"]
1 голос
/ 21 января 2020

Вы можете попробовать этот пример кода:

import re
x = 'anbhb["Text1;Text2;...;TextN"]nbgbyhuyg["Text1;Text2;...;TextN"][]nhj,kji,'
for i in range(len(x)):
    if x[i] == '[' and x[i + 1] == '"':
        while x[i+2] != '"':
            list1 = list(x)
            if x[i] == ';':
                list1[i] = ','
                x = ''.join(list1)

            i = i + 1

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