|
|
|
| Добрый день.
Есть текст, например, "123аа1аиии123ппп1ллл456ц2цц123ввв", из которого надо найти "123ппп1ллл456", т.е. блок, начинающийся с 123 и заканчивающийся на 456.
Между блоками может быть любой текст, любые символы, поэтому приходится использовать ".+?", а в этом случае берется первый блок 123 и все до блока 456.
Исключить можно группу символов, например, [^123], т.е. поиск будет останавливаться на любом из данных символов, а в данном случае внутри текста есть 1 или 2, которые должны быть в результате поиска.
Есть ли какой-нибудь способ найти текст между блоками, но исключая последовательность символов, а не любой из них, например, (123[^123]+?456), но чтобы работало с исключением 123, а не каждого ихз символов. | |
|
|
|
|
|
|
|
для: dtopenya
(02.03.2012 в 20:34)
| | В такой формулировке есть какая-то недоговоренность... ведь 123 = 123, а это означает, что между 123 и 456 не может быть другой последовательности 123, так как регулярное выражение у вас не жадное за счет символа ?. Или внутри вместо 123 может фигурировать какая-то другая последовательность?
PS Независимо от уточнения насколько вы перфекционист? Вам нужно красивое решение, строго регулярными выражениями, или в принципе можно чуть-чуть допилить при помощи PHP-функций? Что потом должно происходить с найденной последовательностью? Её нужно на что-то заменить или она нужна для чего-то другого? | |
|
|
|
|
|
|
|
для: cheops
(02.03.2012 в 20:47)
| | Если бы между 123 и 456 не было цифр, то приведенная мной регулярка сработала бы.
Но там есть цифры 1 и 2, поэтому не пашет, а надо, чтобы между блоками 123 и 456 исключался бы только блок 123, но при этом допускалось сочетание составляющих его цифр.
Данные привел для примера, вместо цифр может быть текст.
Интересует решение регулярным выражением. | |
|
|
|
|
|
|
|
для: dtopenya
(02.03.2012 в 21:07)
| | >Если бы между 123 и 456 не было цифр, то приведенная мной регулярка сработала бы.
>Но там есть цифры 1 и 2, поэтому не пашет, а надо, чтобы между блоками 123 и 456 исключался
>бы только блок 123, но при этом допускалось сочетание составляющих его цифр.
Да, но такую ситуацию корректно обработает следующее регулярное выражение
Однако, я насколько понял, то между 123 и 456 может быть другая последовательность, которую следует исключить, скажем 321? | |
|
|
|
|
|
|
|
для: cheops
(02.03.2012 в 21:30)
| | Было бы неплохо проверить результат перед выкладыванием решения.:)
Регулярка возвращает "123аа1аиии123ппп1ллл456", внутрь затесался блок 123, чего быть не должно.
.+? или .*? выбирают без разбора, а мне надо исключить повторение первого блока между первым и вторым.
321 не равно 123, интересует исключение полного совпадения.
Как должно работать:
"123аа1аиии123ппп1ллл456ц2цц123ввв"
Регулярка находит 123, ищет дальше и спотыкается о блок 123, не находя при этом 456, идет дальше, начиная со второго вхождения 123 в строке, после которого находит 456 и возвращает.
Последнее вхождение 123 также отсекается, т.к. нет блока 456.
Смысл задачи - исключить точное повторение последовательности символов между блоками. | |
|
|
|
|
|
|
|
для: dtopenya
(02.03.2012 в 22:17)
| | Хм... в самом деле, если честно подивился, в моем понимании должен работать (надо Фридла перечитать), впрочем в вашем случае лучше действительно сразу через опережающие или ретроспективные проверки действовать. Можно начать отталкиваться от следующего скрипта
<?php
$str = "123аа1аиии123ппп1ллл456";
$pattern = "|123((?!123).)*?456|";
if(preg_match($pattern, $str, $out))
{
echo $out[0];
}
?>
|
| |
|
|
|
|
|
|
|
для: cheops
(02.03.2012 в 23:17)
| | Работает, спасибо. | |
|
|
|