Ruby dizeyi yakalanan normal ifade deseniyle değiştirir


121

Bunu Ruby'ye çevirmekte sorun yaşıyorum.

İşte tam olarak yapmak istediğimi yapan bir JavaScript parçası:

function get_code(str){
    return str.replace(/^(Z_.*): .*/,"$1")​​​​​​​​​​​​​​​​​​​​​​​​​​​;
}

Ben denedim gsub , alt ve yerini ama hiçbiri ben bekliyorum ne gibi görünüyor.

İşte denediğim şeylerin örnekleri:

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/) { |capture| capture }
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "$1")
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "#{$1}")
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\1")
"Z_sdsd: sdsd".gsub(/(.).*/) { |capture| capture }

Denediğiniz şeyin gerçek kodunu göstermelisiniz.
Amber

@Amber Denediğim örnek koydum.
JD Isaacks

Yanıtlar:


192

'\1'Değiştirmeyi deneyin ( tek tırnak işaretleri önemlidir, aksi takdirde kaçmanız gerekir \):

"foo".gsub(/(o+)/, '\1\1\1')
#=> "foooooo"

Ancak yalnızca yakalama grubuyla ilgileniyor gibi göründüğünüz için, bir dizeyi normal ifadeyle dizine ekleyebileceğinizi unutmayın:

"foo"[/oo/]
#=> "oo"
"Z_123: foobar"[/^Z_.*(?=:)/]
#=> "Z_123"

68
Bunun yalnızca değiştirme dizesi tek tırnak içindeyse çalıştığını unutmayın . Bunu anlamak için 5 dakika harcadım.
Vicky Chijwani

7
@MarkThomas - çoğu zaman ilk önce en iyi / kabul edilen yanıtı, yanıtların tamamını okumadan deneriz. Bu genellikle bir sorunu çözmenin en etkili yolu gibi görünüyor. Vicky'ye bir mola verin! :)
Josh M.

@VickyChijwani Güzel yorum, ama aynı zamanda Ruby inline kullanırken (ile komut satırında -e) çift ​​tırnak görülme olasılığının daha yüksek olduğunu unutmayın : printf "Punkinhead the name" | ruby -ne 'puts gsub /.*(the name)/, "Jonathans \\1"'çünkü sağlanan ifade -egenellikle tek tırnak içine alınır.
Jonathan Komar

Bu, dizedeki tüm kalıp örnekleri için nasıl yapılır?
Jagdeep Singh

1
@JagdeepSingh, It, varsayılan olarak, tüm oluşumların yerini alır.
Iulian Onofrei

36

\1çift ​​tırnaklardan kaçınılması gerekir. Yani ikisini de istiyorsun

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\\1")

veya

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, '\1')

gsub'da "Çift tırnaklı bir dizeyse, her iki geri başvurunun önünde ek bir ters eğik çizgi olmalıdır" yazan belgelere bakın .

Bununla birlikte, sadece maçın sonucunu istiyorsanız, şunları yapabilirsiniz:

"Z_sdsd: sdsd".scan(/^Z_.*(?=:)/)

veya

"Z_sdsd: sdsd"[/^Z_.*(?=:)/]

Unutmayın ki, (?=:)yakalamayan bir gruptur, böylece maçınızda :görünmez.



5

Bazı sonuçları filtrelemek için bir normal ifade kullanmanız gerekiyorsa ve SONRA yalnızca yakalama grubunu kullanıyorsanız, aşağıdakileri yapabilirsiniz:

str = "Leesburg, Virginia  20176"
state_regex = Regexp.new(/,\s*([A-Za-z]{2,})\s*\d{5,}/)
# looks for the comma, possible whitespace, captures alpha,
# looks for possible whitespace, looks for zip

> str[state_regex]
=> ", Virginia  20176"

> str[state_regex, 1] # use the capture group
=> "Virginia"

2
def get_code(str)
  str.sub(/^(Z_.*): .*/, '\1')
end
get_code('Z_foo: bar!') # => "Z_foo"

0

$ değişkenler sadece blokla eşleşecek şekilde ayarlanır:

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/) { "#{ $1.strip }" }

Bu aynı zamanda maçta bir yöntem çağırmanın tek yoludur. Bu, eşleşmeyi değiştirmez, yalnızca strip"\ 1" (değiştirmeden bırakır):

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\\1".strip)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.