[ID CS4-CS6] Выделить текст до первой найденной "стоп"-комбинации

  • Автор темы Автор темы Masia
  • Дата начала Дата начала

Masia

Топикстартер
20 лет на форуме
Сообщения
143
Реакции
65
Здравствуйте,
имеется длинный список, в котором надо выделить фамилии авторов стилем.

===
№ 1. И. О. Фамилия1, И. О. Фамилия2. Название книги, брошюры или чего-то там
№ 2–3. И. О. Фамилия1. Название книги, брошюры или чего-то там. Части 1–2
№ 4. И. О. Фамилия1, И. О. Фамилия2, И. О. Фамилия3, И. О. Фамилия4, И. О. Фамилия5. Название книги, брошюры или чего-то там. Ч. 1. Название части
...
===

Задала правило: (\x{2116}[^\u\l]+)\K.+\.(?=\s\u)
Все бы хорошо, НО оно тормозит только на последней найденной в предложении комбинации.
Пробовала добавлять в правило Repeat в самых разных вариантах, но тоже не получилось.

Как остановить поиск на первой? ;]=
idml примера

фамилии_в_списке.jpg
 
Может пойти от обратного? Покрасить все болдиком, а начиная с названия и до чего-то там болдик отменять.
 
  • Спасибо
Реакции: Masia
(\x{2116}[^\u\l]+)\K(\u\.\h\u\.\h\u\l+\d[,.\h]+)(?2)*
 
И на случай, если будут двойные фамилии
(\x{2116}[^\u\l]+)\K(\u\.\h\u\.\h\u\w+(-\u\w+)*[,.\h]+)(?2)*
 
  • Спасибо
Реакции: LeonidB и Masia
Может пойти от обратного? Покрасить все болдиком, а начиная с названия и до чего-то там болдик отменять.
Пробовала немного для другого такой подход, но получается хуже.

Вот такое можете попробовать:
Код:
(№[^\u\l]+)\K((\u\.\h){1,2}(\u\w+\,?\.?)\h)+(?=\u)
Спасибо, при отсутствии двойных фамилий работает!

И на случай, если будут двойные фамилии
(\x{2116}[^\u\l]+)\K(\u\.\h\u\.\h\u\w+(-\u\w+)*[,.\h]+)(?2)*
Спасибо, работает с двойными фамилиями.

Правило от @LeonidB и @iv-mi работают отлично, если соблюдена четкая структура "И.О. Фамилия" (или двойная фамилия).
Если структура другая, например, автор без отчества или с тройным (иностранные авторы) или присутствует фамильная приставка (типа О’Райли, Волан де Морт), то эти правила не работают. Поэтому я пыталась избежать прямого описания структуры и обобщить, используя в поиске "всё подряд" (.+\.).

Надеюсь, бОльшая часть списка будет соответствовать структуре, остальное уж ручками добью '8)'
 
Если структура другая, например, автор без отчества или с тройным (иностранные авторы) или присутствует фамильная приставка (типа О’Райли, Волан де Морт), то эти правила не работают.
А так все хотелки удовлетворятся:
Код:
(\x{2116}[^\u\l]+)\K((\u\.(\h|-))+(\u[\w']+(((-|\h(\w+\h)+)\u\w+)?)[,.]?)\h)+(?=\u)
?
:)
 
И даже так, а то д'Артаньяна упустил:
Код:
(\x{2116}[^\u\l]+)\K((\u\.(\h|-))+(\w[\w']+(((-|\h(\w+\h)+)\u\w+)?)[,.]?)\h)+(?=\u)
 
А вот с учётом д'Артаньян-заде:
Код:
(\x{2116}[^\u\l]+)\K((\u\.(\h|-))+(\w[\w']+(((-|\h(\w+\h)+)\w\w+)?)[,.]?)\h)+(?=\u)
'))'

Хо Ши Минов, правда, не ловит. Должен быть инициал, хотя бы один.
 
Последнее редактирование:
  • Спасибо
Реакции: RIKITIKI
  • Спасибо
Реакции: RIKITIKI и Masia
Это рекурсивный вызов шаблона поиска. Это не то же самое, что back reference.
На эту тему две или три задачи в курсе "Греп в помомощь вам, друзья мои". Вот одна из них:

30. Рекурсия в поиске
Найти слова, разделённые дефисом и сделать их неразрывными:

Жан-Кристоф Робин-Бобин
чижик-пыжик муха-цекотуха чак-чак
Очевидно решение (\u?\l+)-(\u?\l+)
А что будет, если искать вот так: (\u?\l+)-\1
Это обратная ссылка или адресация в шаблоне поиска.
Программа ищет после дефиса такое же слово, как и до. Но таким поиском мы найдем только чак-чак.
Интереснее познакомиться с таким вариантом поиска
(\u?\l+)-(?1)
Это рекурсивный вызов условия поиска из первых круглых скобок, эта запись короче первой из этого примера, и она найдёт все слова, разделённые дефисом.
 
А вот так и Хо Ши Минов ловит:
Код:
(\x{2116}[^\u\l]+)\K((\u\l*\.?(\h|-))+(\w[\w']+(((-|\h(\w+\h)+)\w+)?)[,.]?)\h)+(?=\u)
Хо Ши Минов ловит '))' И почти все другие случаи отлавливает.
Остались еще некоторые моменты, но они совсем не критичны.

фамилия_хо-ши-мин.jpgфамилия_х-ши-мин.jpg


Не по теме:
Опционально: если в английской версии будет Ю.Г. как Yu.G. , то тоже не поймает. Но это уже пустяки.


В итоге, для себя уяснила, что ограничить поиск первой стоп-комбинацией нельзя, а нужно подробно описывать искомую часть.
 
Остались еще некоторые моменты, но они совсем не критичны.
Вроде проверил и такие, но, возможно, запутался и не то выражение выложил.
Вот такое попробуйте:
Код:
(\x{2116}[^\u\l]+)\K((\u\l*\.?(\h|-))+(\w[\w']+(([-\h][\w']+)+)?[,.]?)\h)+(?=\u)
 
  • Спасибо
Реакции: RIKITIKI и Masia
Скорее всего, ТС это уже не актуально, но и промолчать не могу. Знак «+» это поиск не «до первой комбинации», как написано на скрине, а вовсе даже наоборот «longest possible match will be taken», а самый короткий вариант будет «+?». Видимо, опять лажа в локализации Индизайна.
 
Скорее всего, ТС это уже не актуально, но и промолчать не могу. Знак «+» это поиск не «до первой комбинации», как написано на скрине, а вовсе даже наоборот «longest possible match will be taken», а самый короткий вариант будет «+?». Видимо, опять лажа в локализации Индизайна.
@big bear полезная информация всегда приветствуется :)
Но суть плюса в описании искомого ".+\.(?=\s\u)" заключалась в желании найти: (любой символ (".") повторяющийся сколько угодно раз ("+" One or More Times) после которой стоит точка ("\.") за которой есть "пробел-заглавная" (?=\s\u).
"Первая комбинация" в данном случае - это "пробел-заглавная, стоящая после точки".
Если поставить ".+?\.", то поиск будет останавливаться после первой найденной точки, т.е. после первого инициала.