Konwertuj ciąg na ruby ​​wyrażenia regularnego


118

Muszę przekonwertować ciąg, taki jak „/ [\ w \ s] + /”, na wyrażenie regularne.

"/[\w\s]+/" => /[\w\s]+/

Próbowałem użyć różnych Regexpmetod, takich jak:

Regexp.new("/[\w\s]+/") => /\/[w ]+\//, podobnie Regexp.compilei Regexp.escape. Ale żaden z nich nie wraca tak, jak się spodziewałem.

Co więcej, próbowałem usunąć ukośniki odwrotne:

Regexp.new("[\w\s]+") => /[w ]+/ Ale nie mam szczęścia.

Potem spróbowałem zrobić to prosto:

str = "[\w\s]+"
=> "[w ]+"

To ucieka. W jaki sposób łańcuch znaków mógłby pozostać niezmieniony i przekształcić go w obiekt wyrażenia regularnego?

Odpowiedzi:


149

Wygląda na to, że początkowy ciąg znaków musi być w apostrofach (sprawdź tę stronę )

>> str = '[\w\s]+'
 => "[\\w\\s]+" 
>> Regexp.new str
 => /[\w\s]+/ 

137

Żeby było jasne

  /#{Regexp.quote(your_string_variable)}/

też działa

edit: opakowano your_string_variable w Regexp.quote, dla poprawności.


3
Właśnie dowiedziałem się, że nie możesz w ten sposób dodawać opcji, na przykład /#{your_regex}/#{options}.
pduersteler

Przypuszczam, że mówisz o Railsach? optionsto hash, a Ruby nie jest baaaaardzo dynamiczna =)
Sergey Gerasimov

2
To nie robi tego, o co prosi OP w Rubim 2.1, konwertuje „[\ w \ s] +" => / [w] + /
Luca Spiller,

1
Proszę zauważyć, że odpowiedź została udzielona w 2012 roku :) Wtedy wszystko było idealne
Sergey Gerasimov

4
To był doskonały rok.
Naftuli Kay

35

Ta metoda bezpiecznie usunie wszystkie znaki o specjalnym znaczeniu:

/#{Regexp.quote(your_string)}/

Na przykład .zostanie zmieniony znak ucieczki, ponieważ w przeciwnym razie jest interpretowany jako „dowolny znak”.

Pamiętaj, aby użyć pojedynczego cudzysłowu, chyba że chcesz włączyć zwykłą interpolację ciągów, gdzie ukośnik odwrotny ma specjalne znaczenie.


2
Fajnie, ponieważ wyjaśnia, w jaki sposób możemy chronić zmienną łańcuchową, która może zawierać znaki (takie jak +.), które byłyby zinterpretowane w wyrażeniu regularnym.
rchampourlier

1
To nie robi tego, o co prosi OP w Rubim 2.1, konwertuje "[\ w \ s] +" => / [w \] \ + /
Luca Spiller

@LucaSpiller musisz użyć łańcucha z pojedynczym cudzysłowem, ukośnik odwrotny jest traktowany jako znak specjalny w łańcuchach umieszczonych w podwójnych cudzysłowach, dlatego np. "\n"Jest znakiem nowej linii, ale nim '\n'nie jest.
sandstrom

8

Używanie notacji%:

%r{\w+}m => /\w+/m

lub

regex_string = '\W+'
%r[#{regex_string}]

Z pomocy :

% r [] Interpolowane wyrażenie regularne (flagi mogą pojawić się po ograniczniku zamykającym)


To nie robi tego, o co prosi OP w Rubim 2.1, konwertuje "[\ w \ s] +" => / [ws] + /
Luca Spiller

1
@Luca Spiller, dzięki, powinny tam być używane pojedyncze cudzysłowy, zaktualizuję odpowiedź.
BitOfUniverse

5

Klejnot to_regexp może wykonać pracę.

"/[\w\s]+/".to_regexp => /[\w\s]+/

Możesz także użyć modyfikatora:

'/foo/i'.to_regexp => /foo/i

Wreszcie, możesz być bardziej leniwy, używając komendy: Detect

'foo'.to_regexp(detect: true)     #=> /foo/
'foo\b'.to_regexp(detect: true)   #=> %r{foo\\b}
'/foo\b/'.to_regexp(detect: true) #=> %r{foo\b}
'foo\b/'.to_regexp(detect: true)  #=> %r{foo\\b/}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.