2010-02-22 3 views
12

bölünmüş Bu soruyu daha önce sordum ve bir çoğaltma olduğu için kapatıldı, çünkü ben kabul ediyorum ve yanıtı Java: splitting a comma-separated string but ignoring commas in quotes sorgusunda gerçekten bulduğum için teşekkürler o.Bir ipi çift tırnak içinde içermeyen bir dize üzerinde bir dize

Ama bu yana başka bir sorun haline çalıştırmak. Orada sıfır veya daha çift tırnak sayısı değil, aynı zamanda herhangi görmezden "" parantez içinde bulunan Görünüşe göre ne yapmak gerekir benim ayırıcı olarak kullanılması "" dir.

Yani şu:

"Thanks,", "in advance,", "for("the", "help")" 

olarak tokenize misiniz:

  • Teşekkür önceden
  • için
  • ("", "yardım")
geçerli regex I değiştirmek için yine varsa

emin değilim Buna izin vermek için kullanıyorum ama herhangi bir rehberlik takdir edilecektir.

line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"); 
+0

İstenilen sonuç nedir? – DOK

+12

Bu karmaşayı işlemek için gerçek bir CSV çözümleyici kullanmalısınız. Değil ** her ** ayrıştırma sorunu en iyi ifadeler ile ele alınır. –

+1

@Joachim, Tırnak işaretleri içinde, istediği şekilde tırnak içine alınabilecek kaç tane CSV ayrıştırıcısı olduğunu biliyor musunuz? –

cevap

5

Bazen yerine istemediğiniz ne istediğini maç daha kolaydır:

String s = "\"Thanks,\", \"in advance,\", \"for(\"the\", \"help\")\""; 
String regex = "\"(\\([^)]*\\)|[^\"])*\""; 
Pattern p = Pattern.compile(regex); 
Matcher m = p.matcher(s); 
while(m.find()) { 
    System.out.println(s.substring(m.start(),m.end())); 
} 

Çıktı:

"Thanks," 
"in advance," 
"for("the", "help")" 

ayrıca parantez kapatma görmezden bunu gerekiyorsa

String regex = "\"(\\((\"[^\"]*\"|[^)])*\\)|[^\"])*\""; 
: parantez içindedir tırnak bölümlerinin içinde, o zaman bu ihtiyaç

şu saniye ihtiyacı olan bir dize örneği, daha karmaşık bir versiyonudur:

"foo","bar","baz(":-)",":-o")" 

Çıktı: Ancak

"foo" 
"bar" 
"baz(":-)",":-o")" 

, ben mümkünse veri biçimini değiştirmek için öneriyorum . Jetonlarınızı saklamak için XML gibi standart bir format kullandıysanız bu çok daha kolay olurdu.

3

A yerli ayrıştırıcı kolayca yazılır.

parse 
    : line* 
    ; 

line 
    : Quoted (',' Quoted)* ('\r'? '\n' | EOF) 
    ; 

Quoted 
    : '"' (Atom)* '"' 
    ; 

fragment 
Atom 
    : Parentheses 
    | ~('"' | '\r' | '\n' | '(' | ')') 
    ; 

fragment 
Parentheses 
    : '(' ~('(' | ')' | '\r' | '\n')* ')' 
    ; 

Space 
    : (' ' | '\t') {skip();} 
    ; 

ve dikkate kaçan tırnak veya parantez almak için bu uzatmak kolay olurdu:

Örneğin, bu ANTLR dilbilgisi fazla sorun olmadan örnek girişi ilgilenir.

"Thanks,", "in advance,", "for("the", "help")" 
"and(,some,more)","data , here" 

böyle ayrıştırılır alır:

girdi iki satır aşağıda bu dilbilgisi tarafından oluşturulan ayrıştırıcı beslerken alt text http://i47.tinypic.com/258otvs.png

Bunun için antlr kullanmak düşünün

, İsterseniz, gönderdiğim gramerden ayrıştırıcı almak için biraz NASIL gönderebilirim.