2017-02-04 34 views
2

Я использую Ruby 2.4. У меня есть несколько строк, которые содержат символы, которые имеют особое значение в регулярном выражении. Таким образом, чтобы исключить любую возможность того, что эти символы интерпретируются как символы регулярного выражения, я использую «Regexp.escape», чтобы попытаться избежать их. Тем не менее, я до сих пор, кажется, не в состоянии сделать Дэ ниже регулярное выражение работы ...Почему RegExp.escape не работает в моем выражении Ruby?

2.4.0 :005 > tokens = ["a", "b?", "c"] 
=> ["a", "b?", "c"] 
2.4.0 :006 > line = "1\ta\tb?\tc\t3" 
=> "1\ta\tb?\tc\t3" 
2.4.0 :009 > /#{Regexp.escape(tokens.join(" ")).gsub(" ", "\\s+")}/.match(line) 
=> nil 

Как правильно избежать символы перед заменой пространства с «\ S +» выражение, whcih я хочу интерпретирована как регулярное выражение персонаж?

ответ

2

Когда Regexp.escape(tokens.join(" ")).gsub(" ", "\\s+") выполняется, tokens.join(" ") дает a b? c, то строка избежали ->a\ b\?\ c, а затем gsub выполняется в результате a\\s+b\?\\s+c. Теперь line - 1 a b? c 3. Итак, все \\ теперь соответствуют литеральной обратной косой чертой, они больше не образуют специальный пробел метасимвола regex.

Вам нужно бежать лексем, и присоединиться к \s+ или присоединиться к пространству, а затем заменить пространство \s+:

/#{tokens.map { |n| Regexp.escape(n) }.join("\\s+")}/.match(line) 

ИЛИ

/#{tokens.map { |n| Regexp.escape(n) }.join(" ").gsub(" ", "\\s+")}/.match(line)