2016-05-24 26 views
9

, ben gibi bir düzenli ifade nesnesi tanımlayabilirsiniz:Yakalama dize regex üzerinde Pharo belgelerinden anladığımıza

re := '(foo|re)bar' asRegex 

Ve bu aracılığıyla bir dize ile eşleşti regex değiştirebilirsiniz: Bunun sonucunda: "meh blah meh" ile sonuçlanır.

Şimdiye kadar çok iyi. Ama ben 'bar''u değiştirmek ve ön ekini yalnız bırakmak istiyorum. Bu nedenle, yakalanan parantez işlemek için bir değişken gerekir:

re copy: 'foobar blah rebar' replacingMatchesWith: '%1meh' 

Ve sonuç istiyorum: 'foomeh blah remeh'. Ancak, bu sadece bana verir: '%1meh blah %1meh'. Ayrıca, \1 veya \\1 veya $1 veya {1} kullanmayı denedim ve hazır dizesini değiştirme, , ör. Sonuç olarak, '\1meh blah \1meh'.

Birlikte GNU Smalltalk kolayca yeterince bunu yapabilirsiniz:

'foobar blah rebar' replacingAllRegex: '(foo|re)bar' with: '%1meh' 

Ama hiçbir yere ben Pharo bunu nasıl söyler Pharo regex belgelerinde bulamıyorum. Ben de Pharo regex için bir sürü googling yaptım, ama bir şey değil. Bu yetenek RxMatcher sınıfının veya başka bir Pharo regex sınıfının bir parçası mı?

+0

o Pharo grupları yakalama ile değiştirilmesini desteklemez görünüyor – rock321987

+0

Eh, her zamanki backreferencing stilleri denediniz mi? '\ 1' veya' \\ 1' veya '$ 1' gibi (belki de" MatchReplacedWith "ile)? Yakalama grupları desteklenir, Pharo'da eşleşmenin yapabileceği kadar açıktır, ancak geri başvuruların yedek kalıpların parçaları olarak desteklenip desteklenmediğine dair bir ipucu yoktur. –

+1

@ WiktorStribiżew Evet, \ 1', '\\ 1' ve' $ 1' denedim. Her durumda, yerine, değişmez dize oldu. Bu girişimleri gösteren sorumu güncelledim. Yakalama gruplarının eşleşme kadar desteklendiğini görüyorum. Yakalamaların yakalanması ve numaralandırılması için dokümantasyonda örnekler vardır. Ancak, yedek bir dizide geri gönderme hakkında hiçbir şey. Bu regex'i bul/değiştir bana göre önemli görünüyor, bu yüzden desteklenmediğine şaşırdım. – lurker

cevap

1

vardır, ben RxMatcher#copyStream:to:replacingMatchesWith: seçicinin aşağıdaki değişikliği yaptı:

: o zaman

copyStream: aStream to: writeStream replacingMatchesWith: aString 
    "Copy the contents of <aStream> on the <writeStream>, 
    except for the matches. Replace each match with <aString>." 

    | searchStart matchStart matchEnd | 
    stream := aStream. 
    markerPositions := nil. 
    [searchStart := aStream position. 
    self proceedSearchingStream: aStream] whileTrue: [ | ws rep | 
     matchStart := (self subBeginning: 1) first. 
     matchEnd := (self subEnd: 1) first. 
     aStream position: searchStart. 
     searchStart to: matchStart - 1 do: 
      [:ignoredPos | writeStream nextPut: aStream next]. 

     "------- The following lines replaced: writeStream nextPutAll: aString ------" 
     "Do the regex replacement including lookback substitutions" 
     writeStream nextPutAll: (aString format: self subexpressionStrings). 
     "-------" 

     aStream position: matchEnd. 
     "Be extra careful about successful matches which consume no input. 
     After those, make sure to advance or finish if already at end." 
     matchEnd = searchStart ifTrue: 
      [aStream atEnd 
       ifTrue: [^self "rest after end of whileTrue: block is a no-op if atEnd"] 
       ifFalse: [writeStream nextPut: aStream next]]]. 
    aStream position: searchStart. 
    [aStream atEnd] whileFalse: [writeStream nextPut: aStream next] 

Ve kategorisi "erişimde"

subexpressionStrings 
    "Create an array of lookback strings" 
    | ws | 
    ws := Array new writeStream. 
    2 to: (self subexpressionCount) do: [ :n | | se | 
     ws nextPut: ((se := self subexpression: n) ifNil: [ '' ] ifNotNil: [ se ]) ]. 
    ^ws contents. 

Bu değişiklikle, argümanlar için Smalltalk String#format: modelini kullanarak yeni bir dizede yeniden inceleme yapabilirim:

içinde
re := '((foo|re)ba(r|m))' asRegex 
re copy: 'foobar meh rebam' replacingMatchesWith: '{2}bu{3} (was {1})' 

Sonuçlar:

'foobur (was foobar) meh rebum (was rebam)' 
0

Regex yardımını kontrol ettiniz mi? Hiçbir #replacingAllRegex: olmakla eşleştirici RxMatcher sınıfı ile biraz denedikten sonra #subexpression:

+0

Bu gerçekten bir yorum değil mi? ;) Keşfettiğim Pharo regex ile ilgili tüm çevrimiçi belgeleri okudum (bunlar hemen hemen tüm yinelenen örneklerle aynıdır). Pharo'da '#replacingAllRegex:' olmadığını biliyorum.GNU Smalltalk'ta neler yapabileceğimin bir örneği olarak bunu anladım. Eşleştiricinin "#subexpression" olduğunu biliyorum, ancak bu alt-ifade eşleşmelerine referans veren ve diğer dillerdeki (GNU Smalltalk dahil olmak üzere) regex kitaplıklarında yer alan bir normal ifadenin değiştirilmesi için hiçbir seçici yoktur. Yanılıyorsam, bana bir örnek gösterebilir misin? – lurker