1й случай нормальный - я разбиваю строку регулярным выражением:
"aabaabaa".split /b/
=> ["aa", "aa", "aa"]
А во втором случае, если я понаделую групп то будет какой-то странный результат:
"aabaabaa".split /(b)()/
=> ["aa", "b", "", "aa", "b", "", "aa"]
Хотя для паттерна /(b)()/
первое вхождение: 2й символ;
второе вхождение: 2й символ после первого вхождения.
А третьего вхождения нету, это если вручную искать, но откуда во втором случае берутся клоны соответствий, два пустых места? 0_0
Скобочки в регекспах.
Модератор: Модераторы разделов
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Скобочки в регекспах.
какое-то странное выражение - конкатенация это не самое простое в REGEX... /XY/ означает поиск последовательности X, которая заканчивается только там, где начинается Y, и совпадает совсем не только для XY, если X и/или Y не тривиальны.
-
/dev/random
- Администратор
- Сообщения: 5427
- ОС: Gentoo
Re: Скобочки в регекспах.
jojahti писал(а): ↑26.04.2011 15:321й случай нормальный - я разбиваю строку регулярным выражением:
"aabaabaa".split /b/
=> ["aa", "aa", "aa"]
А во втором случае, если я понаделую групп то будет какой-то странный результат:
"aabaabaa".split /(b)()/
=> ["aa", "b", "", "aa", "b", "", "aa"]
Хотя для паттерна /(b)()/
первое вхождение: 2й символ;
второе вхождение: 2й символ после первого вхождения.
А третьего вхождения нету, это если вручную искать, но откуда во втором случае берутся клоны соответствий, два пустых места? 0_0
Если в разделителе, в качестве которого используется ваше выражение, есть захваты (captures, скобки), то помимо разделяемых фрагментов также возвращаются все захваченные строки, причём из каждого вхождения разделителя.
Т.е., по сути, во втором случае мы получаем: (aa)(b)()(aa)(b)()(aa). А в первом - (aa)b(aa)b(aa).
-
jojahti
- Сообщения: 310
Re: Скобочки в регекспах.
/dev/random
А зачем это сделали? Это же неудобно. Хорошо в руби есть переменные, которые содержат части строки до и после совпадения. А в .Net я пока такой возможности не нашёл.
Если в разделителе, в качестве которого используется ваше выражение, есть захваты (captures, скобки), то помимо разделяемых фрагментов также возвращаются все захваченные строки, причём из каждого вхождения разделителя.
А зачем это сделали? Это же неудобно. Хорошо в руби есть переменные, которые содержат части строки до и после совпадения. А в .Net я пока такой возможности не нашёл.
-
/dev/random
- Администратор
- Сообщения: 5427
- ОС: Gentoo
Re: Скобочки в регекспах.
Это общепринятое поведение. Я ни разу не встречал, чтобы где-то разделение по регекспам вело себя по-другому.
Кому как. Если вам нужно получить и разделённые токены, и разделители, что вы будете делать без этой фичи?
Никогда не работал с .Net, и про него ничего не могу сказать. А в ruby регекспы perl-совместимы, а значит, там есть такая вещь, как (?:regex), группировка без захвата.
-
jojahti
- Сообщения: 310
Re: Скобочки в регекспах.
/dev/random
Ааааа, так вот зачем эта штука нужна! )
Мне интереснее, что мне делать с этой фичей.
То есть если мне нужно найти всё разделённое b, в строке aabaabaa, то мне нужно рисовать что-то такое, пока строка не закончится?
"aabaabaa".match(/(.*)b(.*)/)[-2] - в этом я продолжаю искать.
"aabaabaa".match(/(.*)b(.*)/)[-1] - очередное совпадение.
Жаль точка /./ соответствует не любому символу.
Или выдрессировать встроенный метод split, у меня много вариантов того перед чем и после чего разделитель является разделителем.
>>"aabaabaa".split(/b(?=(?:a|z))/)
=> ["aa", "aa", "aa"]
Кстати, почему вот так не работает? Я же взял в незапоминаемую группу, группу (?=(a|z)).
>>"aabaabaa".split(/b(?:(?=(a|z)))/)
=> ["aa", "a", "aa", "a", "aa"]
а значит, там есть такая вещь, как (?:regex), группировка без захвата.
Ааааа, так вот зачем эта штука нужна! )
Если вам нужно получить и разделённые токены, и разделители, что вы будете делать без этой фичи?
Мне интереснее, что мне делать с этой фичей.
То есть если мне нужно найти всё разделённое b, в строке aabaabaa, то мне нужно рисовать что-то такое, пока строка не закончится?
"aabaabaa".match(/(.*)b(.*)/)[-2] - в этом я продолжаю искать.
"aabaabaa".match(/(.*)b(.*)/)[-1] - очередное совпадение.
Жаль точка /./ соответствует не любому символу.
Или выдрессировать встроенный метод split, у меня много вариантов того перед чем и после чего разделитель является разделителем.
>>"aabaabaa".split(/b(?=(?:a|z))/)
=> ["aa", "aa", "aa"]
Кстати, почему вот так не работает? Я же взял в незапоминаемую группу, группу (?=(a|z)).
>>"aabaabaa".split(/b(?:(?=(a|z)))/)
=> ["aa", "a", "aa", "a", "aa"]
-
/dev/random
- Администратор
- Сообщения: 5427
- ОС: Gentoo
Re: Скобочки в регекспах.
Вы неправильно поняли назначение (?:..). Эта группировка сама не является захватом, но содержать захваты может. Вам нужно каждый ненужный захват преобразовывать из (...) в (?:...).
-
jojahti
- Сообщения: 310
Re: Скобочки в регекспах.
Кстати, всякие позиционные проверки и так не захватываются.