2009-03-10 24 views
4

Yalnızca parantez içinde olmayan virgülle ayırma gibi bir String.split (Java) ifadesinde kullanmak için normal bir ifade yazamadım.Parantez içinde olmayan virgüllere bölünmüş düzenli ifade

Örnek:

(54654,4565) :(45651,65423), 4565: 45651, (4565,4564):

: 45651

3 dizeleri vermelidir

  1. (54654,4565) :(45651,65423)
  2. 4565: 45651
  3. (4565,4564): 45651

Herhangi bir yardım çok takdir edilmektedir.

String regex = "((?<!\\d),)|(,(?!\\d))";

ancak virgül veya diğer bir tarafında bir dizi dışında bir şey olduğunu varsaymaktadır:

+0

Düzenli ifadenin bir çizgi ve kaygan olduğunu biliyoruz, ancak gereksinimleriniz değiştiğinde bunu nasıl değiştireceksiniz? Sadece parens yerine parantez kullanman gerektiğini öğrenirsen yardım ister misin? Ben kendimi 10 satır açık kod görmek istiyorum ... –

cevap

0

Bu çalışır. Bu yüzden, aslında parens içinde olup olmadığınızı değil, sadece rakamlarla çevrelenmiş bir virgülle ayrıldığını görmeyi çok istiyor. Bunun sonucunda

, bu metnin bakıyorsanız:

"45651:65423,4565:45651"

sonra bu çözelti (örnek olarak) başarısız olur. Ne tür girdiler beklediğiniz konusunda daha spesifikseniz, yanıtlarımızı durumunuza göre şekillendirebiliriz.

+0

Ben \\ d: \\ w çiftleri etrafında döner ve bu gibi görünüyor (tek kaçtı) ifade dili: (\ d | \ ((\ d (\ d) * \)): \ d | \ ((\ (w, \ w) * \)) (, (\ d | \ ((\ d (, \ d) * \)): \ d | \ ((\ w (, \ w) * \))) *) Örnek giriş: 4565: çiğ noktası, 4568: (sıcaklık, çiğ noktası), (4565,4568): sıcaklık, (4565,4568): (sıcaklık, çiğ noktası) –

0

Herhangi bir yuvalama olursa dikkatli olmanız gerektiğini hatırlatırız. Regex bu konuda pek iyi değil. Aşağıdaki olsun:

(a) b (c, (d), e) sorunuza dayanarak

, sen virgül b eşleştirmek istediğiniz sadece ederim. Buradaki hileler, ifadelerin genellikle tamamen açgözlü ya da tamamen açgözlü, küçük orta zemine sahip olduklarıdır.

Açgözlü ifadesi en sonunda segmentinin en başında ( ve ) görecekti ve kapanış parantez başka yerde olduğunu olursa olsun, içlerinde herşeyi alır. Hiçbir şey eşleşir.

Başsız bir ifade, en baştan başlayarak mümkün olan en küçük kümeyi alır. Bu virgül b ile eşleşir, ancak bu segmenti bir birim olarak görür: (c,(d,). Daha sonra, son ( zaten alınmış olduğundan, aynı zamanda virgülle e eşleşmeye de devam edecektir.

Yuvalama düzeylerini kullanmanıza izin veren bazı motorlar vardır, ancak ifadeler genellikle çirkin ve bakımı zor olanlardır: en iyisi gerçekten iyi anlamadığınız sürece özelliği kullanmaktan kaçının.

+0

Neyse ki yuvalama benim için bir gereklilik değil, herhangi bir zamanda sadece bir düzeyde parantez var. Basit bir ayrıştırıcı yazdım (üretim kurallarına göre yinelemeli iniş) ama bu sorun çözülebilir olarak bana çarpıyor Doğru düzgün ifade ile daha zarif –

5

Bunu, sadece bir gözle görülebilir.

String[] parts = str.split(",(?![^()]*+\\))"); 

Ama diğer müdahale haklı: Gereksinim değiştirdiğinizde kendi başınıza bu regex ile gelip olamazdı, sen ne yapacaksın? Muhtemelen anladığınız uzun soluklu bir çözümle daha iyi durumdasınızdır.

+0

Teşekkürler Alan, gerçekten işe yarıyor! Ben düzenli ifadeyle sınırlı deneyimim, ancak öğrenme arzusu nedeniyle bu soruyu burada sordum. Gereksinimlerim değişti Benim emrinde yeni bir araca sahip olacağım, daha önce bir bakıma ya da göze çarpmaya maruz kalmamış (tam teşekküllü jeneratörler hariç). –

+0

Bu harika. Regex'ler, programlamanın kirli küçük bir sırrı gibidir. İntiks temelli çözümler sağlamaya çalışan herkes sınırlamalarını ve tuzaklarını belirtme alışkanlığını kazanır, çünkü eğer yapmazsak, başka biri de olacaktır. ;-) –

+0

Çalışıyor, burada bazı Çinli açıklar: http://www.myexception.cn/program/1440342.html http://www.cnblogs.com/wangqishu/archive/2013/05/14/3078239. html – Fwolf