Ошибка в теге, разделенном `|` при использовании Regex python - PullRequest
4 голосов
/ 25 февраля 2020

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

tags = ['XYZ', 'CREF', 'BREF', 'RREF', 'REF']

string_data = 'XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY'

for each_tag in tags:
    result = string_data.replace(each_tag, "|" + each_tag)
    print(result)

Как мне это сделать с помощью Regex?

Строка ввода:

XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY

Фактический результат (неверный):

XYZ:MUMBAI UNIVERSITYC|REF:PUNE UNIVERSITYB|REF:DADAR UNIVERSITYR|REF:KOLHAPUR UNIVERCITY LLC|REF:SOLAPUR UNIVERSITY

Ожидаемый результат:

|XYZ:MUMBAI UNIVERSITY|CREF:PUNE UNIVERSITY|BREF:DADAR UNIVERSITY|RREF:KOLHAPUR UNIVERCITY LLC|REF:SOLAPUR UNIVERSITY

Есть ли способ сделать это с помощью регулярных выражений?

Ответы [ 4 ]

2 голосов
/ 25 февраля 2020

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

Этот шаблон работает:

(XYZ|CREF|BREF|RREF|REF):[a-zA-Z\\s]+?(LLC)?(?=(XYZ|CREF|BREF|RREF|REF)|$)

Объяснение:

  1. (XYZ|CREF|BREF|RREF|REF): : Это очевидно. Вы ищете начало тега. Порядок важен. То есть, сохраните самую короткую подстроку REF в конце.
  2. [a-zA-Z\\s]+? : Соответствует любому символу и пробелу, которые встречаются после тега, неохотно . Неохотно, потому что, если двигатель достигает начала CREF, мы хотим, чтобы он на этом остановился и НЕ принимал больше символов «жадно». Из-за использования «нежелания» порядок тегов в точке (4) имеет значение.
  3. (LLC)? : Это своего рода список исключений всех известных слов, заканчивающихся символом последовательности, с которых могут начинаться теги. (Для этого я не мог придумать другой способ.) Список исключений должен быть известен и может быть отдельно настроен и добавлен во время выполнения шаблона. Если структура входных данных известна заранее и такие исключения ограничены и известны, это не является узким местом. В противном случае, да.
  4. (?=(XYZ|CREF|BREF|RREF|REF)|$) : Ожидание, чтобы убедиться, что двигатель останавливается, когда обнаруживает, что один из тегов подходит. $ позволяет остановить в конце ввода, если тега больше нет.

Это дает следующий вывод для введенной вами входной строки:

XYZ:MUMBAI UNIVERSITY
CREF:PUNE UNIVERSITY
BREF:DADAR UNIVERSITY
RREF:KOLHAPUR UNIVERCITY LLC
REF:SOLAPUR UNIVERSITY

Edit

Добавление кода Python 3.8.1, который я тестировал:

import re

s = "XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY"

p = "(XYZ|CREF|BREF|RREF|REF):[a-zA-Z\\s]+?(LLC)?(?=(XYZ|CREF|BREF|RREF|REF)|$)"

matches = re.finditer( p,s )

tag_list = [ m.group() for m in matches ]
s2 = "|" + "|".join( tag_list )
print( s2 )
1 голос
/ 25 февраля 2020

Можно указать необязательный B или R или C, если ему не предшествовал L с использованием отрицательного взгляда сзади.

(?:[BR]?|(?<!L)C)REF|^(?!\|)

Объяснение

  • (?: Группа без захвата
    • [BR]? Соответствует необязательному B или R
    • | Или
    • (?<!L)C Соответствует C и утверждает, что то, что находится непосредственно слева, не L
  • ) Близкая группа
  • REF Соответствует буквально
  • | или
  • ^(?!\|) Утверждение начала строки, когда непосредственно не следует |, чтобы предотвратить запуск с двойного ||, если он уже присутствует

Regex demo | Python демо

При замене используйте спичку с трубкой

|\g<0>

Например

import re

regex = r"(?:[BR]?|(?<!L)C)REF|^(?!\|)"
test_str = "XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY"
subst = "|\\g<0>"
result = re.sub(regex, subst, test_str)

print (result)

Выход

|XYZ:MUMBAI UNIVERSITY|CREF:PUNE UNIVERSITY|BREF:DADAR UNIVERSITY|RREF:KOLHAPUR UNIVERCITY LLC|REF:SOLAPUR UNIVERSITY
0 голосов
/ 27 февраля 2020

import re

string = "XYZ: MUMBAI UNIVERSITYCREF: PUNE UNIVERSITYBREF: DADAR UNIVERSITYRREF: KOLHAPUR UNIVERCITY LLCREF: СОЛАВУРСКИЙ УНИВЕРСИТЕТ"

regx = "(XYZ | [C] ] REF | REF): [a-zA-Z \ s] +? (LL C)? (? = (XYZ | [C | B | R] REF) | REF | $) "

match = re.finditer (regx, string)

tag = []

для совпадений в матчах: tag.append (match.group ())

result = "|" + "|" .join (tag) print (результат)

0 голосов
/ 25 февраля 2020

Ваша проблема - дублирование между 'CREF', 'BREF', 'RREF' и 'REF' - поскольку 'REF' входит во все остальные три, вы получите дублирующиеся замены, если вы исправите свой код к этому :

tags = ['XYZ', 'CREF', 'BREF', 'RREF', 'REF']

string_data = 'XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY'

for each_tag in tags:
    string_data= string_data.replace(each_tag, "|" + each_tag)
    print(string_data)

Вам необходимо убедиться, что вы заменили 'REF' только в том случае, если перед ним не стоит 'C', 'B' или 'R'.

Обратите внимание, что это может вызвать проблемы в некоторых случаях, таких как XYZ:CARE BEARREF. Т.е. вы можете ожидать |XYZ:CARE BEAR|REF, но вы получите |XYZ:CARE BEA|RREF. Если вы хотите избежать этого, вам нужно быть более точным в отношении фактических правил.

Это работает, если вы знаете, что такого типа проблемы не возникнет:

import re

string_data = 'XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY'

result = re.sub("(XYZ|CREF|BREF|RREF|REF)", r"|\1", string_data )
print(result)

Это позволяет избежать Speci c проверяет, поскольку регулярное выражение учитывает порядок и не будет соответствовать REF после того, как текст уже был найден как часть предыдущих значений.

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