0 / 6 / 0
Регистрация: 10.04.2016
Сообщений: 66
1

Атомарная группировка в PHP

15.06.2016, 02:48. Показов 1678. Ответов 5

Author24 — интернет-сервис помощи студентам
Читаю сейчас всеми известную книгу - Дж.Фридл - "Регулярные выражения". Дошел до момента с атомарной группировкой, и у меня загвоздка. Регулярка обрабатывает котировки вида
23.34000012
23.345
34.4000025
456.0029';.
И должна оставить 3 знака после точки. Имеет вид

"~(\.\d\d(?>[1-9]?))\d+~"

При попытке обработать число 23.345, По идее, как и описано в книге, в группировке должны остаться цифры .345. Но этого не происходит. Сначала совпадает точка \. , далее первая цифра 3 с \d, далее вторая цифра 4 захватывается \d, далее 5 подходит под выражения [1-9], но тогда не находится совпадения для \d+, т.к. должна быть хотя бы одна цифра, следовательно состояние атомарной группировки должно быть уничтожено и \d+ совпадет с цифрой 5. Но этого не происходит...Что не так? поддерживает ли вообще php атомарную группировку. Если да, то в чем отличие с Perl? Или может я че не догнал? У Фридла в книге на Perle типа все работает как задумано? Помогите пожалуйста разобраться...

Код ниже

PHP
1
2
3
4
5
6
7
8
$string = '23.34000012
23.345
34.4000025
456.0029';
 
preg_match_all("~(\.\d\d(?>[1-9]?))\d+~", $string, $matches);
 
print_r($matches);
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.06.2016, 02:48
Ответы с готовыми решениями:

Php группировка из двух таблиц
Привет всем, хочу сделать так, чтобы на сайте выводились только пользователь с которым у меня есть...

Парсинг JSON + группировка массивов - PHP Сети
Здравствуйте, уважаемые форумчане. Давно не заходил сюда и не обращался за помощью, но пришла...

Атомарная операция
Всем добрый день. Я только начал изучать язык и прошу помочь разобраться. Как в методе transfer...

Атомарная операция
У меня есть такой класс: class CClass { public: bool state() const {return state_;}...

5
Hello Kitty
690 / 562 / 402
Регистрация: 12.02.2016
Сообщений: 1,436
Записей в блоге: 1
15.06.2016, 09:56 2
Цитата Сообщение от santaatnas Посмотреть сообщение
\d+
+ Одно или более {1,}
думаю так сработает
PHP
1
preg_match_all("~(\.\d\d(?>[1-9]?))\d*~", $string, $matches);
А еще лучше использовать что то вроде
PHP
1
preg_match_all("~(\.[1-9]{3}|\.[1-9]{2}|\.[1-9]|\.0\d{2}|\.0\d)~", $string, $matches);
---------
PHP
1
2
3
4
5
6
7
8
9
10
11
12
<?php
$string = '23.34000012
23.345
34.4000025
1.10
456.0029';
 
preg_match_all("~(\.\d\d(?>[1-9]?))\d*~", $string, $matches);
 
preg_match_all("~(\.[1-9]{3}|\.[1-9]{2}|\.[1-9]|\.0\d{2}|\.0\d)~", $string, $matches);
 
print_r($matches);
Добавлено через 15 секунд
http://sandbox.onlinephpfuncti... 427e8c46a7
0
0 / 6 / 0
Регистрация: 10.04.2016
Сообщений: 66
15.06.2016, 13:11  [ТС] 3
Спасибо вам за труд, поменять регулярку можно, дело не в поиске решения, а в самой атомарной группировке (?>. ), и в том почему она не корректно себя ведет...
0
0 / 6 / 0
Регистрация: 10.04.2016
Сообщений: 66
15.06.2016, 14:11  [ТС] 4
j2FunOnly, Нет, я немного не дописал, там одним из условий округления идет тот факт, что третья цифра отличная от нуля. Но даже в предложенном Вами варианте, не будет совпадений к числу 23.345. Вот результат по Вашему коду:

PHP
1
Array ( [0] => Array ( [0] => .34000012 [1] => .4000025 [2] => .0029 ) [1] => Array ( [0] => .340 [1] => .400 [2] => .002 ) )
Как видите, только 3 совпадения.

Хотя по идее он должен сработать....В $matches[0] и $matches[1] должно попасть .345, и .34 соответственно....Но почему-то не попадет...
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
15.06.2016, 21:08 5
Лучший ответ Сообщение было отмечено santaatnas как решение

Решение

Цитата Сообщение от santaatnas Посмотреть сообщение
а в самой атомарной группировке (?>. ),
Не слышал такого выражения, но в официальной документации PHP (?> называются однократные подмаски.

Добавлено через 5 минут
Цитата Сообщение от santaatnas Посмотреть сообщение
При попытке обработать число 23.345,
[1-9]? работает в 2 этапа. первый - считает что там есть цифра, второй - считает что цифры там нет. Квалификатор (?> заставляет выполнять только один этап (первый) из всех возможных. Соответственно регулярка считает что эта цифра обязательно должна быть. В Вашем случае (?>[1-9]?) можно заменить на ([1-9]). Это равнозначно.
1
0 / 6 / 0
Регистрация: 10.04.2016
Сообщений: 66
16.06.2016, 02:25  [ТС] 6
pav1uxa, Не суть как это называется, во одних источниках, как http://www.regular-expressions.info/atomic.html, и книге Дж.Фридл, или как в источнике, который вы указали. Спасибо. Я изначально немного не так понял.
0
16.06.2016, 02:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.06.2016, 02:25
Помогаю со студенческими работами здесь

mySql-PHP-группировка-вывод в браузер
Доброе всем время суток, нужна помощь в решении проблемы, я новичок поэтому прошу не судить строго....

Группировка
Доброго времени суток. Не пойму как получить из таблицы: поле1 поле2 666 ввв 777 ууу...

Группировка
Скажите пожалуйста как сгруппировать элементы в Отчете- Анализ Счета по субконто..Например ЕСН и...

Группировка
Здравствуйте. разбираю текстовые логи IIS domain\user ip Select-String -Path C:\tmp\logs\*...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru