Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Тексты > Что не так в регулярке?


Автор: Цербер 12.5.2008, 09:04
Доброе время суток!!!
вся тема состоит в том что нужно вытащить текст из строки указав что этот текст находится между какими то символами!!!
вот сама строка ФИО руководителя</td><td> Фамилия Имя Отчество</td>
вот моя регулярка $name = '/(ФИО руководителя\s<\/td><td>)[А-Яа-я]{1,}\s[А-Яа-я]{1,}\s[А-Яа-я]{1,}(?=<\/td>)/';
ФИО руководителя</td><td> -  находится в левой части от искомой строки.
</td> - находится в правой части искомой строки
[А-Яа-я]{1,}\s[А-Яа-я]{1,}\s[А-Яа-я] а это я пытался указать что там три слова русских и между ними пробел!
прошу строго не судить регулярные выражения плохо знаю по статьям по примерам что то сам пытался сделать!
заранее благодарю!

Автор: amg 13.5.2008, 10:53
Код

'|ФИО руководителя\s*</td>\s*<td>\s*([А-Яа-яёЁ]+\s+[А-Яа-яёЁ]+\s+[А-Яа-яёЁ]+)\s*</td>|'
Захвачено будет (то что в круглых скобках) Фамилия Имя Отчество. Интервалы русских букв не везде правильно работают.

Автор: Цербер 14.5.2008, 07:22
amg 
Код

'|ФИО руководителя\s*</td>\s*<td>\s*([А-Яа-яёЁ]+\s+[А-Яа-яёЁ]+\s+[А-Яа-яёЁ]+)\s*</td>|'

Цитата

Захвачено будет (то что в круглых скобках) Фамилия Имя Отчество. Интервалы русских букв не везде правильно работают.

что то не работает почему то =(

Автор: amg 14.5.2008, 08:23
Работает
Код
$string = 'ФИО руководителя</td><td> Фамилия Имя Отчество</td>';
$regexp = '|ФИО руководителя\s*</td>\s*<td>\s*([А-Яа-яёЁ]+\s+[А-Яа-яёЁ]+\s+[А-Яа-яёЁ]+)\s*</td>|';
preg_match($regexp, $string, $FIO);
echo "$FIO[1]\n";
Но не во всех кодировках. В cp1251 (windows) - нормально. В KOI8-R - нет. Можно заменить А-Яа-я на \xC0-\xFF, и будет нормально в этих двух кодировках. Если юникод - сами разбирайтесь.

Автор: Цербер 14.5.2008, 13:37
amg
Огромнейшее спасибо! действительно работает!
а у меня ещё такая задачка появилась также между символами нужно вытащить номера телефонов если этот номер там один не проблема у меня получается всё нормально! а если их больше и они разделяются "," или другими сепараторами как задать такой шаблон??
заранее благодарствую!!!

$tel = '|Телефоны\s*</td>\s*<td>\s*(\s*\[0-9]*\S*\s*\[0-9]*\S*\s*\[0-9]*\s*)\s*</td>|'; не работает=(

Автор: amg 14.5.2008, 14:47
Как то так
Код
$str = "3-14-15, 911, 02, 1234567, +7-095-1234567, (8-095)123-45-67, 3-33";
preg_match_all("/(?:\(\d{1,2}-\d{3}\)|\+?\d{1,2}-\d{3}-)?\d[\d-]*\d/", $str, $result);
for ($i=0;$i<count($result[0]);$i++) 
    echo $result[0][$i]."\n";


Автор: Цербер 14.5.2008, 15:06
amg
дело в том что числовое значение могут иметь не только телефоны поэтому опять же нужно вытащить их между какими то символами в данном случае это:
Телефоны</td><td> - начало строки
2918043, 2833939, 1200055 - искомый текст
</td> - конец строки
я ещё вот такой вариант использовал но не работает=(
Код

$tel = '|Телефоны\s*</td>\s*<td>\s*([\d*\S*\s*]{1,})\s*</td>|';

Автор: amg 14.5.2008, 15:40
Весь вопрос в том, какие еще данные, кроме собственно телефонов, могут быть внутри тэга. В неблагоприятном случае задачу проще решать  в два шага: сначала выкусить содержимое тэга, и в нем поискать что-то похожее на номера телефонов. Допустимые номера телефонов см. выше.
Код
$str = '
в данном случае это:
Телефоны</td><td> - начало строки
2918043, 2833939, 1200055 - искомый текст
</td> - конец строки
';

$regexp_for_phone = "/(?:\(\d{1,2}-\d{3}\)|\+?\d{1,2}-\d{3}-)?\d[\d-]*\d/";

if (preg_match("|Телефоны\s*</td>\s*<td>((?:.(?!</td>))+)|s", $str, $phones)) {
  preg_match_all($regexp_for_phone, $phones[1], $result);
  for ($i=0;$i<count($result[0]);$i++)
      echo $result[0][$i]."\n";
}


Автор: Цербер 15.5.2008, 08:47
amg
и ещё раз спасибо за оказанную помощь! 
хоть немного стал въежать в тему с регуляркой=)

Автор: Цербер 15.5.2008, 10:54
amg
есть небольшая загвостка в 
Код

$regexp_for_phone = "/(?:\(\d{1,2}-\d{3}\)|\+?\d{1,2}-\d{3}-)?\d[\d-]*\d/";

if (preg_match("|Телефоны\s*</td>\s*<td>((?:.(?!</td>))+)|s", $str, $phones)) {
  preg_match_all($regexp_for_phone, $phones[1], $result);
  for ($i=0;$i<count($result[0]);$i++)
      echo $result[0][$i]."\n";

}

он уже в массиве $phones содержит телефоны, в номере последнего отсутствует последняя цифра=(

Автор: Druidik25 15.5.2008, 11:50
А если к переменной где храниться телефоны добавить один символ в конце.
Мож регулярка откидывает символ?
Добавь в переменную пробел в конце например...

И попробуй выкинуть все переносы строк... Тама тож может быть загвоздка. 

Автор: amg 15.5.2008, 12:56
Цитата(Druidik25 @  15.5.2008,  11:50 Найти цитируемый пост)
Мож регулярка откидывает символ?
Да, так оно и происходит - мой недосмотр. ((?:.(?!</td>))+) означает "захватываем любые символы, после каждого из которых не следует </td>". Символ, находящийся непосредственно перед </td>, этой регулярке, естественно, не подходит - и не захватывается. Надо его добавить: ((?:.(?!</td>))+.) - и будет лучше.

Цитата(Druidik25 @  15.5.2008,  11:50 Найти цитируемый пост)
И попробуй выкинуть все переносы строк... Тама тож может быть загвоздка. 
 Не, с этим не должно быть проблем. В одной регулярке возможность наличия символов переносов строк \n учтена опцией s, в другой просто нет метасимволов ^ $ . - а только они особым образом трактуют \n.

Автор: Цербер 15.5.2008, 13:40
amg,  Druidik25
благодарю за проявленное внимание к моей проблеме!
пометка "решённый" smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)