Интерполяция регулярных выражений в другое регулярное выражение

В следующем кодеk2 минимально отличается отk1, То есть,k2 точно такой же, за исключением того, чтоопределяется с помощью интерполяции. (То есть яожидаемый это должно быть точно так же; Очевидно из результатаp k2 это не.)

v  = /[aeiouAEIOUäöüÄÖÜ]/                 # vowels
k1 = /[[ßb-zB-Z]&&[^[aeiouAEIOUäöüÄÖÜ]]]/ # consonants defined without interpolation
k2 = /[[ßb-zB-Z]&&[^#{v}]]/               # consonants defined same way, but with interpolation

Но, как показано ниже, используяgsub сk1 работает, тогда как используя его сk2 не так, как я неТ понять.

all_chars = "äöüÄÖÜß"

Ответы на вопрос(4)

Используйте строку для хранения этих символов и, при необходимости, интерполируйте ее в регулярные выражения. Руби пытается покрыть некоторые основы(?mix:) но это не такне ожидая, что регулярное выражение входит в набор символов внутри другого регулярного выражения.

Справочная информация

Вот'с чемдействительно происходит:

Во многих случаях, если вы интерполируете регулярное выражение в регулярное выражение, это имеет смысл. Как это

a = /abc/       #/abc/
b = /#{a}#{a}/  #/(?-mix:abc)(?-mix:abc)/

'hhhhabcabchthth'.gsub(/abcabc/, '_')   # "hhhh_hthth"
'hhhhabcabchthth'.gsub(b, '_')          # "hhhh_hthth"

Работает как положено. Целый(?-mix: вещь способ инкапсуляции правил дляa, так, на всякий случайb имеет разные флаги.a чувствителен к регистру, потому что это по умолчанию. Но еслиb был установлен без учета регистра, единственный способ дляa чтобы продолжить сопоставление того, что было найдено ранее, убедитесь, что оно чувствительно к регистру, используя-i, Что-нибудь внутри(?-i:) после того, как двоеточие будет сопоставлено с чувствительностью к регистру. Это становится более понятным из следующего

e = /a/i # e is made to be case insensitive with the /i
/#{e}/   # /(?i-mx:a)/

Вы можете увидеть выше, что при интерполяцииe во что-то, теперь у вас есть(?i-mx:), Теперьi находится слева от-, это означает, что он включает нечувствительность к регистру вместо (временно), чтобыe чтобы соответствовать, как обычно.

Кроме того, чтобы не испортить порядок захвата,(?: добавляется в группу для захвата. Все это грубая попытка сделатьa а такжеe переменные соответствуют тому, что вы ожидаете, что они совпадут, когда вы вставляете их в большее регулярное выражение.

К сожалению, если вы поместите его в соответствие набора символов, то есть[]эта стратегия полностью проваливается.[(?-mix:)] теперь интерпретируется совершенно по-другому.[^?-m] указывает на все, что НЕ между "?" И м" (включительно), что означает, например, букву «с» больше не в вашем наборе символов. Что означает "с" Безразлично»заменить на подчеркивание, как вы видите в своем примере. Вы можете увидеть то же самое, что происходит с буквой «х», Это также неего заменяют подчеркиванием, потому что оно находится в наборе отрицательных символов и, следовательно, не в сопоставляемых символах.

Руби не делаетразобрать регулярное выражение, чтобы выяснить, что выинтерполировать ваше регулярное выражение в набор символов, и даже если это произойдет, ему все равно придется разобратьv переменная, чтобы выяснить, что это также набор символов, и поэтому все, что вы действительно хотите, это взять символы из набора символов вv и поместите их вместе со всеми остальными персонажами.

Мой совет таков:aeiouAEIOUäöüÄÖÜ в любом случае это просто набор символов, вы можете сохранить его в строку и вставить в любой набор символов в регулярном выражении. И будьте осторожны с интерполяцией регулярного выражения в регулярное выражение в будущем. Избегайте этого, если вы действительно не уверены в том, что этособирается сделать.

Ваше заявлениеk2 точно такой же, за исключением того, чтоопределяется с помощью интерполяции " неправильно.

Когда вы интерполируете что-то, что не является строкой, например, регулярное выражениеv, приведено к строке с.to_s

v = /[aeiouAEIOUäöüÄÖÜ]/
v.to_s # => "(?-mix:[aeiouAEIOUäöüÄÖÜ])"

Это интерполируется вk2, в результате чего другое выражение изk1, Если ты хочешьk2 быть таким же, какk1нужно интерполировать строку: "

v = "[aeiouAEIOUäöüÄÖÜ]"
 Owen_R23 мая 2013 г., 05:36
Ваше заявлениеК2 точно такой же, за исключением того, чтоопределяется с помощью интерполяции " неправильно." Ну да, я вижу это изp k2, Я имел ввидупредназначена быть таким же ...
 Owen_R23 мая 2013 г., 05:36
Во всяком случае, это работает:k3 = /[[ßb-zB-Z]&&[^#{v.inspect[1...-1]}]]/

Я делаю такие вещи, как:

keywords = %w[foo bar]
regex = /\b(?:#{ Regexp.union(keywords).source })\b/i
# => /\b(?:foo|bar)\b/i

Тот'полезно, когда вы хотите проверить наличие нескольких подстрок в одной строке одновременно.

Интерполяция регулярного выражения в строку выигралТ обязательно работать правильно. По умолчанию, когда вы делаете это, Ruby преобразует шаблон, используяto_sчто не то, что я хочу, потому что я неЯ хочу полное строковое представление шаблона, флагов и всего. С помощьюsource возвращает то, что я хочу:

regex = Regexp.union(keywords)
regex         # => /foo|bar/
regex.inspect # => "/foo|bar/"
regex.to_s    # => "(?-mix:foo|bar)"
regex.source  # => "foo|bar"
 the Tin Man28 мар. 2017 г., 03:37
stackoverflow.com/q/43057658/128421 имеет больше информации.
 the Tin Man23 мая 2013 г., 17:36
Я думаю, что должно бытьоставил в качестве упражнения для студента ".
 Owen_R23 мая 2013 г., 06:24
Спасибо за совет.source, Не могли бы вы показать мне мин-диф между этим и.inspect[1...-1] Кладж я нашел?
 the Tin Man23 мая 2013 г., 18:02
Чтобы объяснить немного больше:inspect предназначен для того, чтобы дать нам представление о типе и содержимом объекта, а не сериализовать его или использовать для приведения данных, Его можно изменить на очень низком уровне, который внезапно нарушит любой код, делающий то, что вы предлагаете. Покидатьinspect для визуализации содержимого объекта и полагаться на методы и средства доступа, разработанные для истинного принуждения или "stringifying».

Ответь ям с помощью:

Если вы хотите интерполироватьsome_regex в другой, используйтеregex1.inspect[1...-1] внутри .#{}

Например, используя мой оригинальный пример, этот способ определения согласных с помощью интерполяции работает.

v  = /[aeiouAEIOUäöüÄÖÜ]/                   # vowels
k3 = /[[ßb-zB-Z]&&[^#{v.inspect[1...-1]}]]/ # consonants

(Я нене знаю, есть ликакой-то встроенный способ выполнить ту же функцию, что и.inspect[1...-1] для регулярных выражений.

Я был удивлен, что этоне как.to_s работает для регулярных выражений. Я '

Я до сих пор не уверен, что"(?-mix:some_regex)" для.)

 the Tin Man28 мар. 2017 г., 03:38
рекомендую к прочтениюstackoverflow.com/questions/43057658/... как это помогает обратиться к журналу этих "Я нене знаю "," яя удивлен и я'я до сих пор не уверен модификаторы.
 the Tin Man23 мая 2013 г., 06:09
Дон»т использоватьinspectиспользоватьsource, Смотри мой ответ.

Ваш ответ на вопрос