@dimas6000
Изучаю C#

Почему квантификатор {n, } не срабатывает как описано на MSDN?

Пишу приложение, которое должно из шаблонного текста извлекать данные. В т.ч. ФИО. ФИО всегда полностью, например ПЕТРОВ ПЁТР ПЕТРОВИЧ, или СИДОРОВ-ПЕТРОВ СИДОР СИДОРОВИЧ.
Само регулярное выражение выглядит так:
@"(?<=Должник.*)([А-ЯЁ][а-яё]+[\-\s]?){3,}"

Часть текста из которой извлекается ФИО выглядит примерно как под спойлером, но могут пропадать пробельные символы, например запись может быть просто в одну строку.
spoiler
Должник:
ИВАНОВ ИВАН ИВАНОВИЧ

123456,РОССИЯ,Иркутская обл,,Иркутск г,,Несуществующая ул,12,,

Дата рождения: 01.01.1970
Место рождения: РОССИЯ

Вызов регулярного выражения в коде происходит с "RegexOptions.IgnoreCase" т.к. неизвестно в каком регистре будет ФИО. В итоге из текста выше извлекается "ИВАНОВ ИВАН ИВАНОВИЧ " без каких-то проблем. Если добавить в конец регулярки [а-яё], то будет извлекаться без пробела.

Но иногда, во входных данных может попадаться ФИО из двух слов, например как здесь:
spoiler
Должник:
ИВАНОВ ИВАН

123456,РОССИЯ,Иркутская обл,,Иркутск г,,Несуществующая ул,12,,

Дата рождения: 01.01.1970
Место рождения: ТАДЖИКИСТАН

И по какой-то причине регулярное выражение без проблем находит в этом тексте "ИВАНОВ ИВАН ".

В чём причина такого поведения, и как это можно исправить?
В MSDN написано, что квантификатор "{ n ,}" означает, что "Предыдущий элемент повторяется как минимум n раз." Соответственно, я ожидаю что такое регулярное выражение должно находить конструкцию минимум из трёх слов. Но почему-то это не так.
  • Вопрос задан
  • 111 просмотров
Решения вопроса 1
saboteur_kiev
@saboteur_kiev
software engineer
@"(?<=Должник.*)([А-ЯЁ][а-яё]+[\-\s]?){3,}"


[А-ЯЁ][а-яё]+
Вот эта часть распознается, как большая буква и затем маленькие буквы в количестве больше 1. Это точно то, что вы хотели получить? У вас по идее вообще не должно так работать.
Если у вас это работает, значит где-то уровнем выше вы вообще отключили чувствительность к регистру.
Или проще было бы написать [А-ЯЁа-яё]+.

[\-\s]?
Тут выходит что у нас или есть пробел или нет пробела. То есть ИвановИванИванович тоже подойдет.
Думаю надо +, а не ?
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Давайте для начала формализуем задачу.
Необходимо выбрать комбинации из двух или трёх слов, записанных прописными буквами и разделённых пробелами, причём слова могут быть составные через дефис, но не более одного дефиса в слове. Комбинации должны идти после слова "Должник:", между этим словом и комбинацией могут быть только пробельные символы. Всё верно?
(?<=Должник:)\s+([А-ЯЁ]+(?:-[А-ЯЁ]+)?(?:\s[А-ЯЁ]+(?:-[А-ЯЁ]+)?){1,2})
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы