Preg match не работает php

Глюк регулярных выражений в PHP при работе с UTF-8

Нашел такую вещь: если указывать модификатор ‘u’ (PCRE_UTF8), который предписывает интерпретировать шаблон как строку в utf-8 (см. также http://ru2.php.net/manual/ru/reference.pcre.pattern.modifiers.php), для русских букв работает регистронезависимое сопоставление, но в то же время русские буквы не считаются буквами!

Особенно странное заключается в том, что без модификатора буква распознаётся (хотя регистронезависимое сопоставление, конечно же, не работает, что, впрочем, не странно):

Неожиданным оказалось, что, если сохранить скрипт, например, в кодировке cp-1251, то сопоставление букв разного регистра может проходить успешно:

Проверялось всё это на PHP 5.2.4 под Windows.

Немало удивил также результат проверки на PHP 5.1.6 под Linux: отсутсвие совпадения для всех шести описанных случаев, т.е. модификатор PCRE_UTF8 не работает вообще.

Что бы с этим сделать, как думаете?

rgbeast

А работает ли mb_ereg_replace? Функция конечно требует расширение mb. 06.12.2008, 11:06
Ответить

1234ru

echo mb_regex_encoding ( ‘utf-8’ ) ; // выведет 1 — установление кодировки прошло удачно
echo mb_internal_encoding ( ‘utf-8’ ) ; // также выведет 1 (на всякий случай, чтобы внять все вопросы)
echo mb_ereg_match ( ‘/г/ui’ , ‘Г’ ) ; // выводит пустую строку, => совпадения не было
echo mb_ereg_match ( ‘/ \w /u’ , ‘Г’ ) ; // для этого примера и следующих также выводится пустая строка
echo mb_ereg_match ( ‘/г/i’ , ‘Г’ ) ;
echo mb_ereg_match ( ‘/ \w /’ , ‘Г’ ) ;

Такая же ситуация с mb_ereg(). Проверялось под Linux (PHP 5.1.6).

Кстати, я что-то не пойму, зачем было делать две разных функции: mb_ereg() и mb_ereg_match().

rgbeast

Синтаксис у функцмм другой, модификаторов нет:
echo mb_ereg_match(‘г’, ‘Г’);

Опции — третий аргумент

07.12.2008, 01:20
Ответить

1234ru

Да, работает вот так: mb_ereg_match ( ‘г’ , ‘Г’ , ‘i’ ) ; (без модификатора ‘i’, кстати, не работает).

Работает и mb_eregi ( ‘г’ , ‘Г’ ) ; .

Но все равно мне все это не нравится. ereg_match() — отстой, массив вхождений не возвращает. eregi() — тоже — не принимает модификаторы.

Зачем вообще эти ereg()? Ведь надо ж было переделать под mb_ четыре функции: preg_match(), preg_match_all, preg_replace() и preg_replace_callback(). Пока этого нет, будет всё через одно место.

Представь себе это основные функции для работы с регулярками в ПХП.

А preg_& это Perl style, портированный в PHP по просьбам трудящихся.

По поводу того как использовать *ereg* функции, передавать модификаторы и получать вхождения достаточно развернуто сказано на php.net. А по поводу в чем сильные и слабые стороны обоих стандартов холи варов миллион было уже. В т.ч. и сравнительные тесты производительности найти не проблема.

Есть подозрения, что mb_preg* никогда не будет, именно потому что этот стиль подразумевает модификаторы, в т.ч. «u», А в ereg* модификаторов вообще небыло, вместо них плодят разные функции типа ereg i и mb_ereg.

И тут мы плавно подошли к главному, в ereg нет и не надо (!) модификаторов.

echo mb_ereg(‘Г’, ‘Г’); // так матчим
echo mb_eregi(‘г’, ‘Г’); // так матчим регистронезависимо

в обоих случаях 3 параметр — массив вхождений.

1234ru

Что-то не нашел я в описании функции ereg() возможности передавать модификаторы.

Что будем делать, когда понадобятся ‘s’, ‘m’ и др.?

Нередко возникает задача, которую можно решить с помощью PCRE, а с помощью POSIX — нет. Думаю, использовать последние можно лишь не от хорошей жизни, когда разница в производительности даже в 2-3 раза важна, а в остальных случаях смысла я в этом не вижу.

Serg_pnz

1234ru , чем закончились изыскания? Сегодня пол-дня убил, ну не понимает preg_replace когда вводишь fefысывсы

upd: это тоже не прокатило

Serg_pnz

Не фонтан, но вроде работает для моей узкой задачи.

$cp12_pat = iconv ( «UTF-8» , «CP1251» , «a-zA-Zа-яА-Я0-9-_ » ) ;
$regLoginTmp = iconv ( «UTF-8» , «CP1251» , $regLogin ) ;
$regLoginTmp = preg_replace ( ‘/[^’ . $cp12_pat . ‘]/si’ , » , $regLoginTmp ) ;
$regLoginTmp = iconv ( «CP1251» , «UTF-8» , $regLoginTmp ) ;

if ( $regLogin != $regLoginTmp ) <
echo » Служебные символы недопустимы» ;
echo «» ;
$stop += 1 ;
>

2admin: сделайте «шапку» для оформления кода php по примеру цитаты

16.03.2009, 15:57
Ответить

1234ru

1234ru

Изыскания закончились прочтением книги Дж. Фридла про регулярные выражения, в которой написано, что диалект PCRE интерпретирует символ \w точно как ASCII-[A-Za-z0-9] — не включая буквы остальных кодировок, хотя последовательности вида A-Я понимает.

Вам поможет модификатор ‘u’ — preg_replace ( ‘/[A-Za-z0-9А-Яа-я_]+/u’ , » , ‘fefысывсы’ ) вернет пустую строку.

P.S. Извините, что поздно ответил. Диссертация одолевает.

Serg_pnz

Дисс — нужная вещь, я вот в своё время не стал поступать(((

u должна быть u или U?

20.03.2009, 19:58
Ответить

1234ru

Странно.. Что, вот прямо приводимый мной пример не работает?
Какая версия PHP?

Нет, дело не в плюсике. Плюсик на самом деле не нужен (это я нечаянно его поставил, а потом стереть забыл), хотя работать с ним и без него будет почти одинаково.

Да, кстати. У Вас точно файл в UTF-8? Проверьте на всякий случай.

Serg_pnz

В который раз выручили! Всё прекрасно работает и без изврата с перекодировкой.

21.03.2009, 15:01
Ответить

Serg_pnz

Еще одна заморочка для utf-8

Пользователь вводит данные на русском языке и проверка

уже не работает.

Пришлось извратиться так

1234ru

Если $regLoginTmp содержит нелатинские буквы, и данные в UTF-8, то нужно использовать не strlen, а mb_strlen (в стандартном пакете PHP её нет, нужно устанавливать доп. модуль)

Как бы то ни было, с рег. выражением Вы перемудрили: #(.)<1,1># — то же, что просто #.# 🙂
(кстати; вместо <1,1>можно писать просто <1>)

Serg_pnz

dskarataev

Так что же все-таки является самым правильным решением?

1.каждый раз при использовании регулярных выражений делать конвертацию через iconv()
2.переучиваться на синтаксис PHP (ereg)
3.100% решением является использование [a-zA-Zа-яА-Я0-9] и модификатора u

хотелось бы конечно третье 🙂

07.10.2010, 17:27
Ответить

1234ru

Так и есть.
[a-zA-Z\dА-Яа-яЁё] — дедовский способ, который подходит практически для любой кодировки, если там соотв. символы следуют подряд.
100%-ность определяется тем, подряд ли следуют соотв. буквы в таблице символов.

Но есть более правильное решение: конкретно для UTF-8 PHP и Perl поддерживают так называемые свойства Юникода — аналог предопределенных классов (типа \w, \d и др.)

Классы эти имеют вид \p<что-то>. Например, \p — это буквы (есть также полная запись — \p), \p — прописные буквы, \p — кириллические символы и др.
В общем, классов этих куча. Попозже как-нибудь ссылку найду (не забыть бы).

Поэтому современный цивилизованный способ — это выражение вида $pattern = ‘/ \p /u’ ; .

Источник

Почему не работает регулярка на php?

Регулярка на php должна находить слово «культурист» либо в начале строки, либо в конце либо, если оно в середине окружено круглыми скобками например: тест1 (культурист) тест2.

Подскажите, плиз, почему не работают обратные ссылки:

Не находит ничего (найдет только, если слово поставить в конце строки).

1 ответ 1

Небольшое упрощение

Для большей ясности сначала переведу Ваше регулярное выражение в одинарные кавычки:

Все дальнейшие регулярки тоже буду приводить в одинарных кавычках.

Устранение проблемы

Сперва дам простой способ устранения проблемы. Для ваших целей следует использовать такую регулярку:

– то есть вместо обратных ссылок \1 следует использовать рекурсивные подмаски (?1) . Разница в следующем:

  • обратные ссылки сопоставляются с конкретными текстовыми строками, которые были захвачены из текста подмаской
  • рекурсивные подмаски работают как «подпрограммы» – они подставляют указанную подмаску «как есть» на место вызова, независимо от того, какая строка была захвачена ей ранее (см.эквивалентную регулярку ниже)

Потестировать вживую предложенное решение можно здесь: https://regex101.com/r/3hOm5A/1 – заодно я добавил там тестовый пример со всеми кейсами.

Теперь главное: почему так происходит?

В своей регулярке Вы используете обратные ссылки совместно с альтернативным выбором. Как только первая альтернатива (культурист)$ отрабатывает, начинается вторая альтернатива ^\1 . При переходе от альтернативы к альтернативе все обратные ссылки как бы «обнуляются». То есть считается, что в пределах данной (второй) альтернативы ещё никакой текст для первой подмаски не был найден. Подмаска есть, но обратная ссылка уже не хранит текст, который был ей сопоставлен в предыдущей альтернативе. То же самое происходит при переходе к третьей альтернативе. Именно поэтому две последних альтернативы у Вас не работают. Они просто не имеют доступа к ранее найденному тексту.

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

Источник

Не правильно работает функция preg_match()

Здравствуйте, задание: Написать функцию, которая выводит список файлов в заданной директории, которые содержат искомое слово. Директория и искомое слово задаются как параметры функции. Все написал правильно, загвоздка как я понимаю в функции preg_match(), которая должна искать соответствие регулярному выражению и возвращать 1 если соответствие есть, у меня возвращает везде ноль, хотя файл с таким текстом имеется, не могу понять в чем причина, может регулярное выражение составлено неправильно, хотя его проверял на сайте http://regexr.ru/ Ниже привожу полный код php:

P.S. Файл в соотвествующей директории создан и там присутствует искомое слово, проверял. Может дело в кодировке? В файле установил utf-8 без BOM.

1 ответ 1

Если я не ошибаюсь, у функции preg_match есть ограничение на количество принимаемых символов из источника 10000 символов.

Сама функция поиска у вас не совсем правильная: в том, что у вас сейчас есть вы ищите не слово, а просто набор каких-то букв в произвольном порядке, которые ограничиваются пробелами по сторонам. Я бы предложил сделать вот так:

Всё ещё ищете ответ? Посмотрите другие вопросы с метками php регулярные-выражения или задайте свой вопрос.

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.10.19.40496

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

Preg match не работает php

Здесь могла бы быть ваша реклама

Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006
Откуда: Israel

Секрет
Теперь, когда вы уже наверняка второпях отправили свой запрос,
я расскажу вам простой секрет, который сэкономит вам уйму ожиданий,
даже если первый ответ по теме последуем сразу же.

Само собой я знаю что ответят мне тут же, и если я посмотрю
на сообщения на форуме, то пойму что в общем то я и не ошибаюсь.
Но еще я точно замечу, что очень мало тем, в которых всего два ответа :
вопрос автора и еще два сообщение вида Ответ + Спасибо

После этого приходится начинать уточнять этим неграмотным что мне надо.
Они что, сами читать не умеют? А уточнять приходится.
И иногда пока они переварят то что я им скажу проходит и не одна ночь..

Уверен что если бы я им сказал что у меня есть
фиолетовый квадрат, и нужно превратить его в синий треугольник
и я пытался взять кисточку, макнуть в банку и поводить ей по квадрату
но почему то кисточка не принимала цвет краски в банке,
то на мой вопрос — где взять правильные банки мне бы ответили гораздо быстрее
предложив её открыть, а не тратить еще стольник на жестянку.

Поэтому с тех пор я строю свои вопросы по проверенной давным давно схеме:
Что есть
Что нужно получить
Как я пытался
Почему или что у меня не получилось.

На последок как оно происходит на форумах

Новичок: Подскажите пожалуста самый крепкий сорт дерева! Весь инет перерыл, поиском пользовался!
Старожил: Объясни, зачем тебе понадобилось дерево? Сейчас оно в строительстве практически не используется.
Новичок: Я небоскрёб собираюсь строить. Хочу узнать, из какого дерева делать перекрытия между этажами!
Старожил: Какое дерево? Ты вообще соображаешь, что говоришь?
Новичок: Чем мне нравиться этот форум — из двух ответов ниодного конкретного. Одни вопросы неподелу!
Старожил: Не нравится — тебя здесь никто не держит. Но если ты не соображаешь, что из дерева небоскрёбы не строят, то лучше бы тебе сначала школу закончить.
Новичок: Не знаите — лучше молчите! У меня дедушка в деревянном доме живёт! У НЕГО НИЧЕГО НЕ ЛОМАЕТСЯ.
Но у него дом из сосны, а я понимаю, что для небоскрёба нужно дерево прочнее! Поэтому и спрашиваю. А от вас нормального ответа недождёшся.
Прохожий: Самое крепкое дерево — дуб. Вот тебе технология вымачивания дуба в солёной воде, она придаёт дубу особую прочность:
Новичок: Спасибо, братан! То что нужно.

Отредактировано модератором: Uchkuma, 26 Апреля, 2011 — 10:21:12

Источник

Читайте также:  Zabbix не работает веб интерфейс
Оцените статью