Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Регулярка для русскоязычных символов.
Форумы портала PHP.SU » » Вопросы новичков » Регулярка для русскоязычных символов.

Страниц (1): [1]
 

1. Perun - 13 Апреля, 2020 - 13:52:54 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1. $name = 'Иванов Иван Семенович';
  2. $result = preg_match('~^(.+) (.).+ (.).+$~', $name, $matches); // Первый захват делает правильно, а два последующих  ставит как заменяющий символ. Почему?
2. LIME - 13 Апреля, 2020 - 20:55:57 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1. preg_match('~^([а-яА-ЯёЁ]+)\s+([а-яА-ЯёЁ]+)\s+([а-яА-ЯёЁ]+)$~', $name, $matches);
  2.  
Цитата:
(.).+
- это значит: сначала идет что угодно, в том числе и ничего, а за ним что-то что угодно обязательно хоть раз
я вообще удивляюсь как у тебя пых не сломался)
3. Perun - 13 Апреля, 2020 - 21:21:05 - перейти к сообщению
LIME пишет:
PHP:
скопировать код в буфер обмена
  1. preg_match('~^([а-яА-ЯёЁ]+)\s+([а-яА-ЯёЁ]+)\s+([а-яА-ЯёЁ]+)$~', $name, $matches);
  2.  
Цитата:
(.).+
- это значит: сначала идет что угодно, в том числе и ничего, а за ним что-то что угодно обязательно хоть раз
я вообще удивляюсь как у тебя пых не сломался)


Как минимум на RegEx101 все работает правильно.

PHP:
скопировать код в буфер обмена
  1. ^(.+) (.).+ (.).+$~

Берем в:
1. первый захват - один и больше любых одиночных символов - фамилия. Тут не важно пока для простоты - какой регистр и есть ли не буквенные символы.
ОДИН пробел
2. второй захват - любой одиночный символ - первая буква имени и дальше, вне захвата один и больше любых одиночных символов.
ОДИН пробел
3. третий захват - любой одиночный символ - первая буква отчества и дальше, вне захвата - один и больше любых одиночных символов.

Что тут должно было ломаться? Из за того, что вместо \s явные пробелы?
Мне нужно : Вся фамилия, первая буква имени и первая буква отчества. Между фамилией, именем и отчеством на входе - по одному пробелу.

А вот эта строка :
PHP:
скопировать код в буфер обмена
  1. preg_match('~^([а-яА-ЯёЁ]+)\s+([а-яА-ЯёЁ]+)\s+([а-яА-ЯёЁ]+)$~', $name, $matches);
не работает. Не захватывает даже полностью имя и фамилию. Хотя в RegEx101 - тоже работает корректно, как и выражение из первого сообщения.
4. LIME - 13 Апреля, 2020 - 22:39:36 - перейти к сообщению
так тебе инициалы надо
так бы и сказал
попробуй
PHP:
скопировать код в буфер обмена
  1. preg_match('~^(.+) (.).+ (.).+$~uU', $name, $matches);
  2.  

или
PHP:
скопировать код в буфер обмена
  1. [$secondName, $firstName, $lastName] = explode(' ', $name);
  2. $sN = mb_substr($secondName, 0, 1);
5. Perun - 13 Апреля, 2020 - 23:26:59 - перейти к сообщению
LIME пишет:
'~^(.+) (.).+ (.).+$~uU'

Здорово
За флаги совсем забыл. Спасибо!
Но у меня и по ним есть вопросы:
Зачем тут флаг нежадности, если в самом выражении уже все нужное указано?
И с флагом юникода - да, заработало. Но как фамилию то воспринимало правильно, а не спецсимволами? Почему проблема именно в восприятии одиночных букв.
6. LIME - 13 Апреля, 2020 - 23:37:21 - перейти к сообщению
Perun пишет:
Зачем тут флаг нежадности
я просто не помню что из них uU жадность, а что utf

Perun пишет:
Почему проблема именно в восприятии одиночных букв.

utf для кириллических симфолов - 2 байта
без указания модификатора первые байты до пробела были взяты в захват все, что составило правильное слово
после пробела был взят один байт, что не является одной буквой, и криво отображается в utf
7. Строитель - 17 Апреля, 2020 - 20:29:10 - перейти к сообщению
Perun,
PHP:
скопировать код в буфер обмена
  1. $name = 'Иванов Иван Семенович';
  2. $name = preg_replace('~(?:(\p{Lu})\S+)+~u', '$1.', $name);
  3.  
  4. var_dump($name); // 'И. И. С.'
8. LIME - 17 Апреля, 2020 - 20:34:04 - перейти к сообщению
Строитель тогда уж \p{Lu} достаточно
9. Строитель - 17 Апреля, 2020 - 20:35:28 - перейти к сообщению
LIME, не достаточно.
10. LIME - 17 Апреля, 2020 - 20:41:11 - перейти к сообщению
Цитата:
php -r 'preg_match_all("~\p{Lu}~uU", "Иванов Иван Семенович", $m);var_dump($m);'
CODE (htmlphp):
скопировать код в буфер обмена
  1. array(1) {
  2.   [0]=>
  3.   array(3) {
  4.     [0]=>
  5.     string(2) "И"
  6.     [1]=>
  7.     string(2) "И"
  8.     [2]=>
  9.     string(2) "С"
  10.   }
  11. }

(Добавление)
Цитата:
php -r 'var_dump(preg_replace("~(\p{Lu})\S+~u", "$1.", "Иванов Иван Семенович"));'
string(11) "И. И. С."
11. Строитель - 17 Апреля, 2020 - 22:24:23 - перейти к сообщению
LIME пишет:
preg_match_all
Строитель пишет:
preg_replace
12. LIME - 17 Апреля, 2020 - 22:27:11 - перейти к сообщению
Строитель во первых и preg_replace выше есть покороче
зачем брать в захват весь паттерн?))
а во вторых... что тебе плохого сделал preg_match_all? ))
13. Строитель - 18 Апреля, 2020 - 10:43:22 - перейти к сообщению
LIME пишет:
во первых и preg_replace выше есть покороче
Теперь есть, но его не было, и в контексте preg_replace() шаблона \p{Lu} было недостаточно.
LIME пишет:
зачем брать в захват весь паттерн?))
Незачем, тут группировка не нужна, я поспешил.
LIME пишет:
что тебе плохого сделал preg_match_all?
А какой смысл в получении отдельных символов в массив, который снова надо преобразовывать в строку? preg_replace() тут идеальный вариант. Идеальнее неё, разве что твоё решение без регулярок. Хотя не факт, что будет оптимальнее по скорости, не замерял.
14. LIME - 18 Апреля, 2020 - 18:03:48 - перейти к сообщению
Строитель пишет:
А какой смысл в получении отдельных символов в массив, который снова надо преобразовывать в строку? preg_replace() тут идеальный вариант.
я не знаю какой смысл)
не знаю зачем эти букавы понадобились)
наверное ты что-то знаешь
пусть будет так)))

 

Powered by ExBB FM 1.0 RC1