2013-02-15 21 views
5

\G anchor'un normal ifadelerin PHP aromasında nasıl çalıştığını anlamakta zorlanıyorum.Normal ifadede ' G' çapa kullanımı nedir?

Aynı dizgenin birden çok eşleşmesinin gerçekleştiği durumlarda ^ yerine \G'un kullanıldığını düşünmeye (yanlış olsa da) düşünmeye eğilimliyim.

Birisi, \G'un nasıl kullanıldığına dair bir örnek gösterebilir ve nasıl ve neden çalıştığını açıklayabilir mi? Sadece kibrit bir kesintisiz zincir parçası olan sonuç geri

+0

Gerçek bir örnek için bu cevabı inceleyin: http://stackoverflow.com/a/2248130/1606729 – koopajah

+0

@koopajah - teşekkürler. Ne yazık ki, bu uygun bir örnek değil. \ G anchor kullanarak soruyorum; Bağlandığınız örnek, backreference için \ g kullanıyor. –

+0

Tekrar teşekkürler, @koopajah. Yeni örnek gerçekten de \ G kullanıyor, ama bu örnekten hala nasıl ve neden kullanılmalı diye bir şey anlayamıyorum. Gördüğüm tek şey, \ G'nin orada kullanıldığını, ama neden kullanıldığını, diğer durumlarda hangi durumlarda kullanılması gerektiğini, vb. - Bunu anlamıyorum. Daha fazla örnek, lütfen? –

cevap

3

GÜNCELLEME G \

desen zorlar. İlk maçtan sonraki her maçın bir maçtan önce gelmesi gerekir. Zinciri kırarsan maçlar bitiyor. düz docs

Tersbölünün dördüncü kullanımı dan

<?php 
$pattern = '#(match),#'; 
$subject = "match,match,match,match,not-match,match"; 

preg_match_all($pattern, $subject, $matches); 

//Will output match 5 times because it skips over not-match 
foreach ($matches[1] as $match) { 
    echo $match . '<br />'; 
} 

echo '<br />'; 

$pattern = '#(\Gmatch),#'; 
$subject = "match,match,match,match,not-match,match"; 

preg_match_all($pattern, $subject, $matches); 

//Will only output match 4 times because at not-match the chain is broken 
foreach ($matches[1] as $match) { 
    echo $match . '<br />'; 
} 
?> 

Bu bazı basit tezleri içindir. Bir iddiası, bir konudaki belirli bir noktasında, konu dizesinden herhangi bir karakter tüketmeden karşılanması gereken bir koşulu belirtir. Daha karmaşık iddialar için alt-desenlerin kullanımı aşağıda tarif edilen 'dur. ters bölü işareti iddialar mevcut uygun pozisyon maçın başlangıç ​​noktası de olduğu zaman preg_match ofset bağımsız değişken() tarafından belirtilen şekilde

\G 
    first matching position in subject 
\ G savı doğrudur bulunmaktadır. Ofset değeri sıfırdan farklı olduğunda \ A'dan farklıdır.

http://www.php.net/manual/en/regexp.reference.escape.php

Sen bu sayfayı, biraz aşağı kaydırmak zorunda kalacak ama öyle

.

Yakutta gerçekten iyi bir örnek var ama php'de aynı.

How the Anchor \z and \G works in Ruby?

+0

Teşekkür ederim @Jrod, bu benim için doğru yönde bir adımdır, ve ben de sizin Dokümanlar için bağlantı. Ne yazık ki, PHP'ye ve genel olarak programlamaya nispeten yeni olmanın, o şeyin gerçek ve pratik anlamını belgelerden hiç anlamadım. Bu yüzden bir örnek istiyorum. –

+0

@DimitriVorontzov Basit bir örnek ekledim. Umarım bunu daha net yapar. – Jrod

+0

Bu harika, çok teşekkürler @Jrod! –

4

\G dizenin başında veya son maçın son karakteri tüketilen nokta ya Eşleşme sınırı, maç olacak.

Karmaşık belirtme işlemi yapmanız gerektiğinde ve ayrıca belirteçlerin geçerli olduğundan emin olmanız özellikle yararlıdır.(Ben dizenin sonunu belirtmek için ~ kullanın) bu jeton içine

input 'some input in quote' more input '\'escaped quote\'' [email protected]_$of_fun ' \' \\ ' crazy'stuff' 

:

input~ 
some input in quote~ 
more~ 
input~ 
'escaped quote'~ 
[email protected]_$of_fun~ 
' \ ~ 
crazy~ 
stuff~ 

Örnek problem

bize bu girişi tokenizing örneğini ele alalım Dize, aşağıdakilerin bir karışımından oluşur:

    \ ve ''un çıkmasına izin veren tek tırnaklı dizgi ve boşluklar korunur. Boş dize tek tırnaklı dizgi kullanılarak belirtilebilir.
  • VEYA beyaz olmayan boşluk karakterlerinden oluşan bir diziden oluşan ve \ veya ' içermeyen, ayrıştırılmamış dize.
  • 2 dizilemeyen dize arasındaki boşluk bunları sınırlandıracaktır. Diğer durumları sınırlamak için alan gerekli değildir. Basitlik açısından

, (Eğer gerçek durumda bunu dikkate ihtiyacını) bize girdi yeni satır içermiyor varsayalım. Noktayı göstermeden normal ifadenin karmaşıklığına katkıda bulunur.

tek başına alıntı dize için RAW regex '(?:[^\\']|\\[\\'])*+'
Ve tırnaksız dize için RAW regex Gerçi yukarıdaki regex 2 parça çok fazla önemsemeye gerek yok [^\s'\\]++
olduğunu.

\G aşağıda çözüm motoru herhangi eşleşme bulmak için başarısız olduğunda, son maçın pozisyonuna dizinin başlangıcından itibaren tüm karakter tüketildiğine dair emin olabiliriz. Karakter atlayamayacağından, dizgenin geri kalanında rastgele şeyler yakalamak yerine, her iki belirtim belirtimi için geçerli bir eşleşme bulunamadığında, motor eşleşmeyi durduracaktır.

inşaatın ilk adımda İnşaat

, bunu birlikte regex koyabilirsiniz: koymak

\G(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++)) 

Veya sadece (bu değil regex - sadece daha kolay okunmasını sağlamak için):

\G(Singly_quote_regex|Unquoted_regex) 

Bu, yalnızca ilk belirteciyle eşleşeceği zaman, 2. kez eşleşen pts, maç 'some input...'dan önce boşlukta durur.


Biz sadece müteakip maçında, pozisyonda boşluk son maçında tarafından bıraktığı o tüketilen böylece, 0 veya daha fazla alan yaratmak için biraz eklemek gerekir

:

\G *+(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++)) 

Yukarıdaki regex, here görüldüğü gibi jetonları doğru bir şekilde tanımlayacaktır.münavebe soldan sırayla çalışılmıştır yana

\G *+(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++)|((?s).+$)) 

: Motor herhangi bir geçerli kodunu almasına başarısız olduğunda o dizenin kalanını döndürmesini sağlayacak şekilde


regex daha da değiştirilebilir -onunca, son seçenek olan ((?s).+$), eğer sadece dize geçerli bir tek tırnaklı veya seçilmemiş bir jeton oluşturmazsa eşleşecektir. Bu, hatayı kontrol etmek için kullanılabilir.

birinci yakalama grubu (burada gerçekten ilgili değildir, bu yüzden okuyucular için bir egzersiz olarak bırakın) ihtiyaçları ekstra işleme istenilen metne çevirmek için tek tırnaklı dize içindeki metni içerecektir. İkinci yakalama grubu, tırnaksız dizeyi içerecektir. Ve üçüncü yakalama grubu, giriş dizesinin geçerli olmadığını gösteren bir gösterge olarak işlev görür.

Demo for the final regex

Sonuç

Yukarıdaki örnek simgelileştirme içinde \G kullanımına bir senaryo gösterilmektedir olup. Karşılaşmamam gereken başka kullanımlar olabilir.

+0

Teşekkürler! Örnek kesinlikle sofistike, analiz edeyim. –

+1

@DimitriVorontzov: Bu daha çok gerçek bir durum kullanımından ibaret, bu yüzden oldukça karmaşık. – nhahtdh

+0

Evet, bunu takdir ediyorum, @nhahtdh! –

İlgili konular