Почему последнее выражение в моем регулярном выражении конкатенируется к первому? - PullRequest
0 голосов
/ 27 августа 2009

Язык Ruby, вот мой сеанс irb

expr = /\Aselect from (\D+)(?: (?:where|&&) (\D+) (\S+) (\S+))*(?: order by (\D+) (asc|desc))?\Z/
=> /\Aselect from (\D+)(?: (?:where|&&) (\D+) (\S+) (\S+))*(?: order by (\D+) (asc|desc))?\Z/

/> str = "select from Entity order by value desc"
=> "select from Entity order by value desc"

/> expr =~ str
=> 0

/> $1
=> "Entity order by value desc"

/> $2
=> nil

Я просто не понимаю, почему я получаю "Порядок сущностей по значению desc" как 1 доллар. Желаемое поведение здесь - получить $ 1 => "Entity", $ 2 => "value", $ 3 => "desc". Что я делаю неправильно? Как изменить это регулярное выражение, чтобы получить эти результаты?

Спасибо

Ответы [ 2 ]

4 голосов
/ 27 августа 2009

\ D - это «не цифра», которая закрывает пробел между словами, а также следующими словами. Попробуйте (\ S +) вместо этого.

[Редактировать] Извините, в конце я пропустил вопрос. Вышеприведенное отвечает на вопрос «почему это происходит?», Но не «как мне добиться того, чего я хотел?». Вот один из способов, обходя любые другие пункты с помощью. *

/\Aselect from (\S+).*(?:order by (\S+) (asc|desc)?)?\Z/

Поскольку SQL довольно свободен с пробелами и так далее между ключевыми словами, вы можете сделать его более нечитаемым и использовать \ s + вместо литеральных пробелов. То есть выражение «как есть» не будет совпадать:

"select   from     Fred"

но было бы, если бы вы сделали /\Aselect\s+from\s+....

1 голос
/ 27 августа 2009

(\D+) является жадным и съел остаток строки. Поскольку все остальное в вашем выражении является необязательным (* или?), Нет необходимости сопоставлять его для успешного выполнения выражения.

Я предлагаю сделать ваши спички менее жадными. например, (\D+?) будет сопоставлять и фиксировать любые нецифровые символы один или несколько раз, но столько раз, сколько необходимо для успешного сопоставления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...