Ruby normal ifadesinin ilk eşleşmesini döndür


97

Ruby'de bir dizge üzerinde normal ifade eşlemesi yapmanın ve ilk eşleşmede kısa devre yaptırmanın bir yolunu arıyorum.

matchİşlediğim dize uzun ve standart yol ( yöntem) gibi göründüğünden , her şeyi işler, her eşleşmeyi toplar ve tüm eşleşmeleri içeren bir MatchData nesnesi döndürür.

match = string.match(/regex/)[0].to_s

Yanıtlar:


134

Deneyebilirsin variableName[/regular expression/]. Bu irb'den örnek bir çıktıdır:

irb(main):003:0> names = "erik kalle johan anders erik kalle johan anders"
=> "erik kalle johan anders erik kalle johan anders"
irb(main):004:0> names[/kalle/]
=> "kalle"

Bu bir maç yapıp sahne arkasındaki ilk sonucu döndürmek değil mi?
Gishu

7
Çeşitli uzunluktaki dizelerle yapılan bazı karşılaştırmalardan ve C kaynağına baktıktan sonra, Regex.match'in kısa devre yaptığı ve yalnızca ilk eşleşmeyi bulduğu ortaya çıktı.
Daniel Beardsley

3
Neat, bu kısayolu bilmiyordum.
Pierre

Bu kısayolla ilgili bazı belgeler var mı? Görece basit bir görev olduğunu düşündüğüm şeyi yüksek ve düşük aradım ve sorunumu ancak bunu bulduktan sonra çözdüm. Teşekkürler!
dmourati

5
@dmourati Bu özelliği String # [] 'da belgelenmiş olarak bulabilirsiniz . Dokümanla ilgili soru sorduğunuz için teşekkürler, çünkü onu okurken captureargümanı buldum - bu da tam eşleşme yerine bir yakalama döndürmenizi sağlar.
slothbear

69

Kullanabilirsiniz []: (gibi match)

"foo+account2@gmail.com"[/\+([^@]+)/, 1] # matches capture group 1, i.e. what is inside ()
# => "account2"
"foo+account2@gmail.com"[/\+([^@]+)/]    # matches capture group 0, i.e. the whole match
# => "+account2"

4
en iyi tam cevap
akostadinov

23

Sadece bir maçın varlığı önemliyse,

/regexp/ =~ "string"

Her iki durumda da, dizenin tamamı boyunca arama matchyapılırken yalnızca ilk isabeti döndürmelidir scan. Bu nedenle eğer

matchData = "string string".match(/string/)
matchData[0]    # => "string"
matchData[1]    # => nil - it's the first capture group not a second match

8

Henüz bu özelliğin harika mı yoksa tamamen çılgın mı olduğundan emin değilim, ancak normal ifadeniz yerel değişkenleri tanımlayabilir.

/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
dollars #=> "3"

(Http://ruby-doc.org/core-2.1.1/Regexp.html adresinden alınmıştır ).


Harika özellik! Tam ihtiyacım olan şey
RaphaMex

Uyarı: yalnızca regex =~ string", not when string = ~ regex` olduğunda çalışır
Christopher Oezbek

2

Normal İfade (regex), sonlu durum makinesinden (FSM) başka bir şey değildir.

FSM, "Bu durum mümkün mü, değil mi?" Sorusunu yanıtlamaya çalışır.

Bir eşleşme bulunana kadar (başarılı olana) veya tüm yollar keşfedilene ve eşleşme bulunmayana (başarısızlık) kadar bir model eşleşmesi yapmaya çalışır.

Başarı üzerine, "Bu durum mümkün mü, değil mi?" "evet" ile yanıtlandı. Bu nedenle başka eşleştirme gerekmez ve normal ifade döner.

Bununla ilgili daha fazla bilgi için buna ve buna bakın .

Dahası: burada, normal ifadenin nasıl çalıştığını gösteren ilginç bir örnek var . Burada, bir verme sayısının asal olup olmadığını saptamak için bir normal ifade kullanılır. Bu örnek perl içindedir, ancak yakutla da yazılabilir.

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.