Как заменить запятые в списке имен, разделенных запятыми - PullRequest
2 голосов
/ 20 сентября 2019

В Python у меня есть строка имен, разделенных запятыми, и я пытаюсь добавить двойные квадратные скобки вокруг имен.

Вот формат исходной строки.
1. John Smith1, John Smith2, John Smith3, etc.<br>

В итоге я хочу получить следующее:
1. [[John Smith1]], [[John Smith2]], [[John Smith3]], [[etc.]]<br>

Я пытался использовать это регулярное выражение:
(.+?)(?:, |(<br>)$)

с этой заменой:
[[\1]], \2

Но он дает такой результат:
[[1. John Smith1]], [[John Smith2]], [[John Smith3]], [[etc.,]]<br>

  1. Как переместить начальные "\ d. \ S" за пределы захвата имени?
  2. Как предотвратить использование последней запятой после фамилии (в данном случае и т. Д., А не и т. Д.)?

Любой совет будет принят с благодарностью.

ОБНОВЛЕНИЕ
Приношу свои извинения за то, что не конкретизировал.Когда я заявил, что хочу сопоставить это, я должен был сказать «только» этот шаблон.

Когда я использовал это регулярное выражение: (?<=\.\s|,\s)([^,\r\n]+)\s*(?=<br>|,) и эту замену [[\1]], он сделал две неожиданные вещи.
1. Хотя это работает на regex101.com, когда я смотрю на вывод в Notepad ++, все имена меняются на SOH, а в Notepad они становятся непечатными символами.
2. Это слишком агрессивно, поэтому оно изменилоськаждый экземпляр из нескольких элементов, разделенных запятыми.Таким образом, вывод из этого:
1. John Smith1, John Smith2, John Smith3, John Smith4<br>
This is the reason why John Smith1, John Smith2, John Smith3, and John Smith4 did what they did.<br>

выглядит так в Notepad ++:

1. [[SOH]], [[SOH]], [[SOH]], [[SOH]]<br>
This is the reason why John Smith1, [[SOH]], [[SOH]], and John Smith4 did what they did.<br>

Я дам другим предложениям попробовать посмотреть, есть ли работа.

Еще раз спасибо.

Последнее обновление Я решил проблему, не связанную с печатью.Я забыл экранировать строку подстановки в регулярном выражении с помощью «r».Теперь, если я смогу заставить регулярное выражение остановиться на первом <br>, я должен получить то, что мне нужно.Продолжаем поиск ...

Еще одна вещь: в строке будет больше пронумерованных строк с разделенными запятыми именами и описаниями с разрывами строк.Так что

1. FirstName1 LastName1, FirstName2 LastName2, FirstName3 LastName3<br>  
Description with FirstName1 LastName1, FirstName2 LastName2, FirstName3 LastName3<br>

2. FirstName3 LastName3, FirstName4 LastName4<br>  
Description with FirstName3 and FirstName4 LastName4.<br>

3. FirstName3 LastName3, FirstName6 LastName6<br>  
Description with FirstName3 and FirstName6.<br>

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

1. [[FirstName1 LastName1]], [[FirstName2 LastName2]], [[FirstName3 LastName3]]<br>  
Description with FirstName1 LastName1, FirstName2 LastName2, FirstName3 LastName3<br>  

2. [[FirstName3 LastName3]], [[FirstName4 LastName4]]<br>  
Description with FirstName3 and FirstName4 LastName4.<br>  

3. [[FirstName3 LastName3]], [[FirstName6 LastName6]]<br>  
Description with FirstName3 and FirstName6.<br>

Не соответствует слову «Описание».Используется только в качестве примера.

Ответы [ 4 ]

1 голос
/ 20 сентября 2019

Может быть, какое-то выражение, похожее на

(?<=\.\s|,\s)([^,\r\n]+)\s*(?=<br>|,)

и замену,

[[\1]]

тоже может быть вариантом.

Test

import re

regex = r"(?<=\.\s|,\s)([^,\r\n]+)\s*(?=<br>|,)"
test_str = ("1. John Smith1, John Smith2, John Smith3, etc.<br>\n"
    "12. John Smith1, John Smith2, John Smith3, etc.<br>")
subst = "[[\\1]]"

print(re.sub(regex, subst, test_str))

Вывод

1. [[John Smith1]], [[John Smith2]], [[John Smith3]], [[etc.]]<br>
12. [[John Smith1]], [[John Smith2]], [[John Smith3]], [[etc.]]<br>

Если вы хотите упростить / изменить / изучить выражение, это объяснено на верхней правой панели regex101.com .Если хотите, вы также можете посмотреть в эту ссылку , как она будет сопоставляться с некоторыми примерами ввода.


0 голосов
/ 20 сентября 2019

Вы можете попробовать что-то вроде этого

(^\d\.\s*)?(\s*)(?:([^,]+)(?=, |<br>$))

Заменить на

\1\2[[\3]]

enter image description here

Regex Demo

Если пробел после , не всегда есть, тогда вы должны заменить положительный прогноз на (?=.\s*|<br>)

0 голосов
/ 20 сентября 2019

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

Regex + манипуляции со строками

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

import re
st = '1. John Smith1, John Smith2, John Smith3, etc.<br>'
re1 = r"(\d\.\s)*(.+?)(?:, |(<br>)$)"
new_st = re.sub(re1, r"\1[[\2]], \3", st)
print(new_st)

, что дает нам значение:

new_st = '1. [[John Smith1]], [[John Smith2]], [[John Smith3]], [[etc.]], <br>'

Обратите внимание на последнюю запятую в конце.Мы можем удалить это с помощью:

new_st = ''.join(new_st.rsplit(", ", 1))

, что дает нам:

'1. [[John Smith1]], [[John Smith2]], [[John Smith3]], [[etc.]]<br>'

, так что в целом у вас будет:

import re
st = '1. John Smith1, John Smith2, John Smith3, etc.<br>'
re1 = r"(\d\.\s)*(.+?)(?:, |(<br>)$)"
new_st = re.sub(re1, r"\1[[\2]], \3", st)  # notice I do capture the first group
new_st = ''.join(new_st.rsplit(", ", 1))

Извлеките ядро, затемиспользовать split / join

Здесь также используется регулярное выражение, но только для извлечения core строки.Затем используйте комбинацию соединения / разделения для достижения желаемого результата:

import re
st = '1. John Smith1, John Smith2, John Smith3, etc.<br>'
re2 = r"(\d+\.\s+)(.+)(<br>)$"
sections = re.findall(re3, st)

# just to make it clearer i'll split the sections
the_number, the_core, the_end = sections[0]

# rework the core
the_core = ']], [['.join(the_core.split(','))

# glue all the pieces together adding what's missing
new_st = the_number + '[[' + the_core + ']]' + the_end

, что дает в результате:

'1. [[John Smith1]], [[ John Smith2]], [[ John Smith3]], [[ etc.]]<br>'
0 голосов
/ 20 сентября 2019

вы можете сделать это так

import re

st = "1. John Smith1, John Smith2, John Smith3, etc.<br>"

re.findall(r"(?:\d\. )?(.*?)(?:, |<br>)", st)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...