Вытащить фамилии

Статус
В этой теме нельзя размещать новые ответы.

BSunV

Профессор
Регистрация
8 Окт 2008
Сообщения
186
Реакции
45
Помогите составить регулярку, а то моих познаний в этой области явно недостаточно.
Есть текст:
В основе этой фамилии одно из старых русских имен Агап (просторечное Агапей, старое Агопий), Агапион или Агапит, в переводе с греческого – ‘любить, любовь, любимый’. Имен этих сейчас почти уже не встретишь, однако от них и их производных (в частности, Ганя, Гаша, Агаша) образовались фамилии Агапеев, Агапьев, Агашков, Гапеев, Гашев.
Возможно, в этот же ряд стоит поставить фамилии Агашин, Гашин (сын Агаши, Гаши), но велика вероятность образования этих фамилий от женского имени Агафья (в переводе с греческого – ‘добрая, хорошая’).

Нужно составить регулярное выражение, позволяющее вытащить фамилии из текста.
Я понимаю, что в данном случае невозможно составить выражение, которое будет вытаскивать только фамилии. Например в данном примере оно будет вытаскивать и имя Агафья (или я ошибаюсь?). Приемлем вариант, когда будет вытаскивать и имена и фамилии. Я потом буду чистить вручную.
 
если вы пытаетесь парсить контент какого-то сайта, возможно стоит привязаться к его тегам?
 
Нет, это не парсинг контента сайта. Есть просто текстовый файл, из которого нужно вытащить фамилии.
 
тогда пробуйте
PHP:
$reg = '#([А-Я][а-я]+)#';
 
Если текста много, а потеря нескольких фамилий не критична, то можно сначала удалить первые слова в предложении или заменить у них прописную буквы на строчную, иначе они попадут в выборку вместе с именами/фамилиями.
PHP:
$reg = "#\.[\s][А-Я][а-я]*#"
 
У меня такой пхп код:
PHP:
$fp=fopen("fam.txt", "r");   //из этого файла читаем
$name = fopen("name.txt", "w");   //сюда пишем результат

while (!feof($fp))         //до конца файла  fam.txt
{
$order = fgets($fp, 500);     //считываем одну строку

	if (ereg("([А-Я][а-я]+)", $order, $regs))   //Результат, соответствующий регулярке сохраняется в массиве $regs

	{
	 $temp = $regs[0]."\r\n";   //Добавляем к каждому элементу перевод каретки на новую строку   
	 fputs($name, $temp);    //Результат пишем в name.txt
     }

}
fclose($fp);
fclose($name);

В результате работы скрипта в результирующем файле только два слова:
Агап
Возможно
(в файле fam.txt находиться только абзац, который я привел в начале темы).
Где ошибка?
 
в приведеном вами тексте, сколько строк и сколько совпадений вы ищите в каждой строке?
 
ищу все совпадения,т.е.если попадается несколько фамилий, то должны вытащиться все. В данном случае должна вытаскивать все слова,начинающиеся с большой буквы. Понимаю что будет много мусора(в виде заглавных букв строки и имен), с этим буду бороться после того,как хоть в таком виде скрипт заработает. Т.е если кратко, то нужно вытащить все слова, начинающиеся с заглавной буквы.
 
я задавал вопрос именно по вашей реализации и вашим входным параметрам. в примере из первого сообщения можно получить всего две строки, ereg, в свою очередь, сработал по принципу preg_match и вернул всего лишь один результат. Рекомендую заменить функцию ereg на preg_match_all.
 
Заменил строчку
if (ereg("([А-Я][а-я]+)", $order, $regs))
на
if (preg_match_all("([А-Я][а-я]+)", $order, $regs, PREG_SET_ORDER))
и все заработало. Спасибо. И последний момент. В руководстве для по регуляркам для начинающих:
Внутри функции, которая будет выполнять операцию со строкой при помощи вышеприведенного условия, совпадение будет запоминаться в специальных переменных, в PHP к ней можно обращаться через \1 в Perl - $1. В одном условии поиска может быть несколько инструкций запоминания: ([a-z]{5})([1-8]{4}) - проверит строку на совпадение с условием, в случае удачного совпадения, запомнит пять букв в \1 ($1), четыре цифры в \2 ($2). Если обратиться к переменной \0, то окажется, что в ней хранится вся совпавшая строка, которая была описана условием.

как обращаться к этой переменной(?) \1 (меня интересует сам синтаксис). В книгах по рег.выражениям и пхп не нашел. Пробовал обращаться к ней по-разному - и как к переменной и как к массиву. не получается. спасибо
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху