2013-11-22 29 views
5

Sadece regex en kullanmayı öğreniyorum:Regex en iyi uygulamaları

Ben <:==]:> ve <:==}:> tarafından sınırları çizilmiş iki farklı tür bölüme ayrılmıştır bir metin dosyasında okuyorum. Ben bir ] veya } yüzden sadece yapamaz

pattern.compile("<:==]:>|<:==}:>"); pattern.split(text) 

Bunu yapmak olsun her bölüm için bilmek gerekir:

pattern.compile("<:=="); pattern.split(text) 

çalıştığını ve o zaman sadece ilk karakter bakabilirsiniz her bir alt dize içinde, ama bu bana özensiz görünüyor ve sanırım ben sadece ona başvuruyorum çünkü tam bir şey kavramak değil regex hakkında kavramak gerekir:

Burada en iyi uygulama ne olurdu? Ayrıca, her bir sınırlayıcı ile başlayacak şekilde sonuçlanan dizgelerde sınırlayıcıdan ayrılırken bir dizgiyi ayırmanın herhangi bir yolu var mıdır?

DÜZENLEME: dosyası bu gibi dışarı atılır:

Old McDonald had a farm 
<:==}:> 
EIEIO. And on that farm he had a cow 
<:==]:> 
And on that farm he.... 
+0

Benim ilk çözüm (bir yakalama grubundaki sınırlayıcı içine) (Python gibi diğer diller çalışmış olurdu) Java çalışmamasına görüntülenir, bu yüzden bu yeniden düşünmek gerekir. Küçük bir örnek dosya verebilir misiniz? Tam olarak bölümlerin nasıl sınırlandığını anladığımdan emin değilim. Sınırlayıcı çiftlerle çevreleniyorlar mı, yoksa bir sınırlayıcıdan sonra bir bölüm çalışıyor ve bir sonraki sınırlayıcıyla bitiyor mu? –

+0

@TimPietzcker Evet Aynısını gerçekleştirdim. Dosyanın nasıl oluşturulduğuna dair bir örnek için düzenlememe bakın. Bunlar, sınırsız çiftler değildir, her birinin sonu, bir sonrakiin başlangıcı ile işaret edilir. Ayrıca, <:?:> etiketinin diğer birçok tipte işaret ettiğine dikkat etmeliyim – drewmoore

+0

Peki, çıktı olarak tam olarak ne istiyorsunuz? Metin bölümü ya bir ']' veya '}' ile birlikte mi? Eğer öyleyse, sınırlandırılmamış olan ilk/son bölüm için ne istiyorsunuz? Metnin bölümüne ihtiyacınız var mı yoksa sadece sınırlayıcıları almak için yeterli mi? – OGHaza

cevap

6

Bunun için split() kullanmamayı daha iyi bir fikir olabilir. Bunun yerine bir maç yapabileceğini:

List<String> delimList = new ArrayList<String>(); 
List<String> sectionList = new ArrayList<String>(); 
Pattern regex = Pattern.compile(
    "(<:==[\\]}]:>)  # Match a delimiter, capture it in group 1.\n" + 
    "(     # Match and capture in group 2:\n" + 
    " (?:    # the following group which matches...\n" + 
    " (?!<:==[\\]}]:>) # (unless we're at the start of another delimiter)\n" + 
    " .    # any character\n" + 
    ")*    # any number of times.\n" + 
    ")     # End of group 2", 
    Pattern.COMMENTS | Pattern.DOTALL); 
Matcher regexMatcher = regex.matcher(subjectString); 
while (regexMatcher.find()) { 
    delimList.add(regexMatcher.group(1)); 
    sectionList.add(regexMatcher.group(2)); 
} 
+1

Tamamen bunu kestirdiniz gibi görünüyor. Bütün soruların cevabının evet olduğunu düşünüyorum. Ayrıntılar için, [Jan Goyvaerts tarafından düzenli ifadeler öğretici] (http://www.regular-expressions.info/tutorial.html), özellikle [yakalama grupları] bölümleri (http: //www.regular-expressions) .info/brackets.html) ve [lookaround assertions] (http://www.regular-expressions.info/lookaround.html). Son sorunuz için daha spesifik olabilir misiniz? Belki de başka bir soru şeklinde, yorumlar bunun için gerçekten uygun değil midir? –

+0

Bu örneği yorumları ile beğeniyorum, ancak statik bir düzenli ifadenin genellikle statik olarak (bir kez) derlendiğini ve birden çok kez yeniden kullanıldığını unutmayın. Ayrıca bkz: http://stackoverflow.com/questions/4935216/shouldnt-static-patterns-always-be-static ayrıca bkz http://stackoverflow.com/questions/1360113/is-java-regex-thread-safe –

İlgili konular