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.

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"

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


6

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

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

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

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.