Скобочки в регекспах.

Модератор: Модераторы разделов

Аватара пользователя
jojahti
Сообщения: 310

Скобочки в регекспах.

Сообщение jojahti »

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: Скобочки в регекспах.

Сообщение drBatty »

jojahti писал(а):
26.04.2011 15:32
А во втором случае, если я понаделую групп то будет какой-то странный результат:
"aabaabaa".split /(b)()/

какое-то странное выражение - конкатенация это не самое простое в REGEX... /XY/ означает поиск последовательности X, которая заканчивается только там, где начинается Y, и совпадает совсем не только для XY, если X и/или Y не тривиальны.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5427
ОС: Gentoo

Re: Скобочки в регекспах.

Сообщение /dev/random »

jojahti писал(а):
26.04.2011 15:32
1й случай нормальный - я разбиваю строку регулярным выражением:
"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: Скобочки в регекспах.

Сообщение jojahti »

/dev/random
Если в разделителе, в качестве которого используется ваше выражение, есть захваты (captures, скобки), то помимо разделяемых фрагментов также возвращаются все захваченные строки, причём из каждого вхождения разделителя.

А зачем это сделали? Это же неудобно. Хорошо в руби есть переменные, которые содержат части строки до и после совпадения. А в .Net я пока такой возможности не нашёл.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5427
ОС: Gentoo

Re: Скобочки в регекспах.

Сообщение /dev/random »

jojahti писал(а):
26.04.2011 15:58
А зачем это сделали?

Это общепринятое поведение. Я ни разу не встречал, чтобы где-то разделение по регекспам вело себя по-другому.

jojahti писал(а):
26.04.2011 15:58
Это же неудобно.

Кому как. Если вам нужно получить и разделённые токены, и разделители, что вы будете делать без этой фичи?

jojahti писал(а):
26.04.2011 15:58
Хорошо в руби есть переменные, которые содержат части строки до и после совпадения. А в .Net я пока такой возможности не нашёл.

Никогда не работал с .Net, и про него ничего не могу сказать. А в ruby регекспы perl-совместимы, а значит, там есть такая вещь, как (?:regex), группировка без захвата.
Спасибо сказали:
Аватара пользователя
jojahti
Сообщения: 310

Re: Скобочки в регекспах.

Сообщение jojahti »

/dev/random
а значит, там есть такая вещь, как (?:regex), группировка без захвата.

Ааааа, так вот зачем эта штука нужна! )

Если вам нужно получить и разделённые токены, и разделители, что вы будете делать без этой фичи?

Мне интереснее, что мне делать с этой фичей. :D

То есть если мне нужно найти всё разделённое 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: Скобочки в регекспах.

Сообщение /dev/random »

jojahti писал(а):
26.04.2011 16:57
Кстати, почему вот так не работает? Я же взял в незапоминаемую группу, группу (?=(a|z)).
>>"aabaabaa".split(/b(?:(?=(a|z)))/)
=> ["aa", "a", "aa", "a", "aa"]

Вы неправильно поняли назначение (?:..). Эта группировка сама не является захватом, но содержать захваты может. Вам нужно каждый ненужный захват преобразовывать из (...) в (?:...).
Спасибо сказали:
Аватара пользователя
jojahti
Сообщения: 310

Re: Скобочки в регекспах.

Сообщение jojahti »

Кстати, всякие позиционные проверки и так не захватываются.
Спасибо сказали: