2011-12-28 18 views
91

Potrzebuję konwertować ciąg znaków jak "/ [\ w \ s] + /" do wyrażenia regularnego.Konwertuj ciąg na wyrażenie regularne ruby ​​

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

Próbowałem przy użyciu różnych metod Regexp jak:

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

Co więcej Próbowałem usuwanie backslashy:

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

Następnie próbowałem zrobić to proste:

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

on ucieka. Jak teraz łańcuch może pozostać niezmieniony i przekonwertować go na obiekt regexp?

Odpowiedz

111

Wygląda tu trzeba początkowy ciąg być w apostrofach (patrz this page)

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

Żeby było jasne

/#{Regexp.quote(your_string_variable)}/ 

pracuje zbyt

EDIT: owinięty your_string_variable w Regexp.quote, dla poprawności.

+2

Właśnie dowiedziałem się, że _can't_ dołączeniu opcje w ten sposób, takie jak '/ # {your_regex}/# {options}'. – pduersteler

+0

Przypuszczam, że mówisz o Railsach? 'options' jest hasłem, a Ruby nie jest soooo dynamic =) –

+0

Ah, tak. Próbowałem przekazać "ix" :) – pduersteler

33

Ta metoda będzie bezpiecznie uciec wszystkie znaki o specjalnym znaczeniu:

/#{Regexp.quote(your_string)}/ 

Na przykład . będzie uciec, ponieważ jest inaczej interpretowana jako „dowolny znak”.

Pamiętaj, aby użyć ciągów o pojedynczych cudzysłowach, chyba że chcesz wprowadzić regularną interpolację napisów, w której odwrotny ukośnik ma specjalne znaczenie.

+2

Miło, ponieważ wyjaśnia, w jaki sposób możemy chronić zmienną łańcuchową, która może zawierać znaki (takie jak '+ .'), która byłaby interpretowana w Regexp. – rchampourlier

+1

To nie robi tego, co OP pyta o Ruby 2.1, konwertuje "[\ w \ s] +" =>/\ [w \ \] \ +/ –

+0

@ LucaSpiller, musisz użyć ciągu pojedynczego, ukośnik odwrotny jest traktowany jako znak specjalny w cudzysłowach, dlatego np '' \ n "' jest znakiem nowej linii, ale '' \ n'' nie jest. – sandstrom

5

funkcji% oznaczenia:

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

lub

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

Z help:

% R [] Interpolacja regexp (flagi może pojawić się po zamknięciu separatora)

+0

To nie robi tego, co OP pyta o Ruby 2.1, konwertuje "[\ w \ s] +" =>/[ws] +/ –

+0

@ Luca Spiller, dziękuję, należy tam użyć pojedynczych cudzysłowów, zaktualizuj odpowiedź. – BitOfUniverse

2

Klejnot to_regexp może wykonać pracę.

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

Można również użyć modyfikatora:

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

Wreszcie, można być bardziej leniwy, używając: wykryć

'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/}