Wyrażenie regularne Ruby używające nazwy zmiennej

105

Czy jest możliwe utworzenie / użycie wzorca wyrażenia regularnego w języku Ruby, który jest oparty na wartości nazwy zmiennej?

Na przykład wszyscy wiemy, że za pomocą ciągów języka Ruby możemy wykonać następujące czynności:

str = "my string"
str2 = "This is #{str}" # => "This is my string"

Chciałbym zrobić to samo z wyrażeniami regularnymi:

var = "Value"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "a test foo"

Oczywiście to nie działa tak, jak podano, umieszczam to tylko jako przykład, aby pokazać, co chciałbym zrobić. Muszę dopasować wyrażenie regularne na podstawie wartości zawartości zmiennej.

cpjolicoeur
źródło

Odpowiedzi:

184

Kod, który Twoim zdaniem nie działa, działa:

var = "Value"
str = "a test Value"
p str.gsub( /#{var}/, 'foo' )   # => "a test foo"

Sprawy stają się bardziej interesujące, jeśli zmienna może zawierać metaznaki wyrażenia regularnego. Jeśli tak i chcesz, aby te znaki matematyczne robiły to, co zwykle robią w wyrażeniu regularnym, zadziała ten sam gsub:

var = "Value|a|test"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "foo foo foo"

Jeśli jednak wyszukiwany ciąg zawiera metaznaki i nie chcesz, aby były one interpretowane jako metaznaki, użyj Regexp.escape w następujący sposób:

var = "*This*"
str = "*This* is a string"
p str.gsub( /#{Regexp.escape(var)}/, 'foo' )
# => "foo is a string"

Lub po prostu podaj gsub ciąg znaków zamiast wyrażenia regularnego. W MRI> = 1.8.7, gsub potraktuje argument zastępujący ciąg jako zwykły ciąg, a nie wyrażenie regularne:

var = "*This*"
str = "*This* is a string"
p str.gsub(var, 'foo' ) # => "foo is a string"

(Kiedyś było tak, że argument zastępujący ciąg znaków w gsub był automatycznie konwertowany na wyrażenie regularne. Wiem, że tak było w 1.6. Nie pamiętam, która wersja wprowadziła zmianę).

Jak wspomniano w innych odpowiedziach, możesz użyć Regexp.new jako alternatywy dla interpolacji:

var = "*This*"
str = "*This* is a string"
p str.gsub(Regexp.new(Regexp.escape(var)), 'foo' )
# => "foo is a string"
Wayne Conrad
źródło
4
Wskazówka dotycząca Regexp.escape była tym, czego nie wiedziałem, że potrzebuję. Dzięki!
Jeff Paquette,
regxPlayerVariable = '(. *?) =. *? document \ .getElementById (# {pluginPlayeVariable})' w tym zastosowałem wszystko powyżej, ale te nie działają.
SSP
1
@SSP Dobrze byłoby wyjaśnić problem w osobnym pytaniu.
Wayne Conrad,
13

Działa, ale musisz użyć gsub!lub przypisać powrót do innej zmiennej

var = "Value"
str = "a test Value"
str.gsub!( /#{var}/, 'foo' )  # Or this: new_str = str.gsub( /#{var}/, 'foo' )
puts str
FMc
źródło
9

tak


str.gsub Regexp.new(var), 'foo'
DigitalRoss
źródło
6

Możesz używać wyrażeń regularnych poprzez zmienne w Rubim:

var = /Value/
str = "a test Value"
str.gsub( /#{var}/, 'foo' )
GeekTantra
źródło
1
Nie jestem pewien, dlaczego ma to tylko głosy przeciw. Wypróbowałem to i działa, mimo że nie potrzebujesz ukośników regex zarówno w varzmiennej, jak i w pierwszym parametrze gsub.
Tyler Collier
Myślę, że celem ukośników w gsub było pokazanie, że wyrażenie regularne może zawierać zmienną, która sama jest wyrażeniem regularnym. Zmienna nie musi być typu string (i faktycznie regex jest lepszy z powodów przedstawionych w odpowiedzi Wayne'a).
mahemoff