Biểu thức chính quy Ruby sử dụng tên biến


105

Có thể tạo / sử dụng một mẫu biểu thức chính quy trong ruby ​​dựa trên giá trị của một tên biến không?

Ví dụ, tất cả chúng ta đều biết chúng ta có thể làm như sau với chuỗi Ruby:

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

Tôi muốn làm điều tương tự với biểu thức chính quy:

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

Rõ ràng là điều đó không hoạt động như được liệt kê, tôi chỉ đặt nó ở đó như một ví dụ để hiển thị những gì tôi muốn làm. Tôi cần so khớp regexp dựa trên giá trị nội dung của một biến.

Câu trả lời:


184

Mã bạn nghĩ không hoạt động, không:

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

Mọi thứ trở nên thú vị hơn nếu var có thể chứa các ký tự meta biểu thức chính quy. Nếu đúng như vậy và bạn muốn các ký tự matacharacter đó làm những gì họ thường làm trong một biểu thức chính quy, thì gsub tương tự sẽ hoạt động:

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

Tuy nhiên, nếu chuỗi tìm kiếm của bạn chứa siêu ký tự và bạn không muốn chúng được hiểu là siêu ký tự, thì hãy sử dụng Regexp.escape như sau:

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

Hoặc chỉ cung cấp cho gsub một chuỗi thay vì một biểu thức chính quy. Trong MRI> = 1.8.7, gsub sẽ coi đối số thay thế chuỗi là một chuỗi thuần túy, không phải là một biểu thức chính quy:

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

(Trước đây, một đối số thay thế chuỗi thành gsub đã được tự động chuyển đổi thành một biểu thức chính quy. Tôi biết nó là như vậy trong phiên bản 1.6. Tôi không nhớ phiên bản nào đã giới thiệu thay đổi).

Như đã lưu ý trong các câu trả lời khác, bạn có thể sử dụng Regexp.new thay thế cho phép nội suy:

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

4
Gợi ý về Regexp.escape chỉ là những gì tôi không biết mình cần. Cảm ơn!
Jeff Paquette

regxPlayerVariable = '(. *?) =. *? document \ .getElementById (# {pluginPlayeVariable})' trong điều này tôi đã áp dụng tất cả ở trên nhưng chúng không hoạt động.
SSP

1
@SSP Có thể giải thích sự cố trong một câu hỏi riêng.
Wayne Conrad

13

Nó hoạt động, nhưng bạn cần sử dụng gsub!hoặc gán giá trị trả về cho một biến khác

var = "Value"
str = "a test Value"
str.gsub!( /#{var}/, 'foo' )  # Or this: new_str = str.gsub( /#{var}/, 'foo' )
puts str


6

Bạn có thể sử dụng biểu thức chính quy thông qua các biến trong ruby:

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

1
Tôi không chắc tại sao điều này chỉ có phản đối. Tôi đã thử và nó hoạt động, mặc dù bạn không cần dấu gạch chéo regex trong cả vartham số đầu tiên của biến và gsub.
Tyler Collier

Tôi nghĩ rằng điểm của các dấu gạch chéo trong gsub là cho thấy rằng một regex có thể chứa một biến mà bản thân nó là một regex. Biến không nhất thiết phải là kiểu chuỗi (và trên thực tế, regex tốt hơn vì những lý do được nêu trong câu trả lời của Wayne).
mahemoff

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.