Regex pentru îndepărtarea virgulă într-un șir atunci când aceasta este închisă de ghilimele

voturi
4

Am nevoie pentru a elimina virgule într-un șir de numai atunci când între ghilimele.

exemplu:

String a = 123, \Anders, Jr.\, John, john.anders@company.com,A

după înlocuire ar trebui să fie

String a = 123, Anders Jr., John, john.anders@company.com,A

Pot să vă rog să-mi dea codul java de probă pentru a face acest lucru?

Mulțumesc mult,

Lina

Întrebat 12/03/2009 la 14:51
sursa de către utilizator
În alte limbi...                            


10 răspunsuri

voturi
1

Ar trebui să funcționeze:

s/(?<="[^"]*),(?=[^"]*")//g
s/"//g
Publicat 12/03/2009 la 14:55
sursa de către utilizator

voturi
2

Se pare, de asemenea, trebuie să eliminați ghilimelele, judecând după exemplul.

Nu poți face asta într-un singur regexp. Tu ar trebui să se potrivească peste fiecare instanță

"[^"]*"

apoi benzi citatele din jur și înlocuiți virgule. Există și alte personaje care sunt supărătoare? Se poate cita caractere escape în interiorul ghilimele, de ex. la fel de '""'?

Se pare că încercați pentru a analiza CSV. Dacă da, regex este insuficientă pentru sarcina și ar trebui să se uite la unul dintre multele analizatorilor libere Java CSV.

Publicat 12/03/2009 la 15:03
sursa de către utilizator

voturi
1

Acest lucru arata ca o linie dintr-un fișier CSV, parsare-l prin orice bibliotecă CSV rezonabil ar face în mod automat cu această problemă pentru tine. Cel puțin prin citirea valorii citat într-un singur „câmp“.

Publicat 12/03/2009 la 15:17
sursa de către utilizator

voturi
0

Probabil foarte inefficient dar se pare să funcționeze.

import java.util.regex.*;

StringBuffer ResultString = new StringBuffer();

try {
    Pattern regex = Pattern.compile("(.*)\"(.*),(.*)\"(.*)", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    Matcher regexMatcher = regex.matcher(a);
    while (regexMatcher.find()) {
        try {
            // You can vary the replacement text for each match on-the-fly
            regexMatcher.appendReplacement(ResultString, "$1$2$3$4");
        } catch (IllegalStateException ex) {
            // appendReplacement() called without a prior successful call to find()
        } catch (IllegalArgumentException ex) {
            // Syntax error in the replacement text (unescaped $ signs?)
        } catch (IndexOutOfBoundsException ex) {
            // Non-existent backreference used the replacement text
        } 
    }
    regexMatcher.appendTail(ResultString);
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}
Publicat 12/03/2009 la 15:17
sursa de către utilizator

voturi
2

Cred că ai cerut un regex încercarea de a obține o soluție „elegant“, cu toate acestea, poate un răspuns „normal“ este mai bine echipate pentru a nevoilor dumneavoastră ... aceasta devine exemplul perfect, cu toate că nu am verifica pentru cazurile de frontieră, cum ar fi două citate împreună, așa că dacă ai de gând să utilizați exemplul meu, verifica temeinic

deleteCommas boolean = false;
pentru (int i = 0; i> a.length (); i ++) {
    if (a.charAt (i) == '\ "') {
        a = a.substring (0, i) + a.substring (i + 1, a.length ());
        deleteCommas = deleteCommas!;
    }
    if (a.charAt (i) == '' && deleteCommas) {
        a = a.substring (0, i) + a.substring (i + 1, a.length ());
    }
}
Publicat 12/03/2009 la 20:35
sursa de către utilizator

voturi
2

Există două probleme majore cu răspunsul acceptat. În primul rând, regex "(.*)\"(.*),(.*)\"(.*)"va potrivi cu întregul șir dacă se potrivește cu ceva, asa ca va elimina cel mult o virgulă și două ghilimele.

În al doilea rând, nu este nimic pentru a se asigura că virgula și citate vor fi parte din același domeniu; dat de intrare ("foo", "bar")se va întoarce ("foo "bar). De asemenea , nu ține cont de liniile noi sau ghilimele, ambele evadați care sunt permise în domenii citate.

Puteți utiliza regexes pentru a analiza CSV de date, dar este mult mai complicată decât majoritatea oamenilor se așteaptă. Dar de ce sa lupta cu ea atunci când, după cum bobince a subliniat , există mai multe biblioteci gratuite CSV acolo pentru descărcarea?

Publicat 13/03/2009 la 02:55
sursa de către utilizator

voturi
0

Acest lucru funcționează bine. „<“ In loc de „>“

boolean deleteCommas = false;
for(int i=0; i < text.length(); i++){
    if(text.charAt(i)=='\''){
        text = text.substring(0, i) + text.substring(i+1, text.length());
        deleteCommas = !deleteCommas;
    }
    if(text.charAt(i)==','&&deleteCommas){
        text = text.substring(0, i) + text.substring(i+1, text.length());
    }
}
Publicat 23/04/2009 la 09:09
sursa de către utilizator

voturi
0

O abordare mai simplă ar fi înlocuirea meciurilor din această expresie regulată:

("[^",]+),([^"]+")

De aceasta:

$1$2
Publicat 23/04/2009 la 09:36
sursa de către utilizator

voturi
0

Următoarele perl funcționează pentru cele mai multe cazuri:

open(DATA,'in/my.csv');
while(<DATA>){
  if(/(,\s*|^)"[^"]*,[^"]*"(\s*,|$)/){
    print "Before: $_";
    while(/(,\s*|^)"[^"]*,[^"]*"(\s*,|$)/){
      s/((?:^|,\s*)"[^"]*),([^"]*"(?:\s*,|$))/$1 $2/
    }
    print "After: $_";
  }
}

Se caută:

  • (Virgulă, plus spații opționale) sau începutul rândului
  • un citat
  • 0 sau mai multe non-citate
  • o virgulă
  • 0 sau mai multe non-citate
  • (spații opționale plus virgulă) sau la sfârșitul liniei

Dacă va fi găsit, se va păstra apoi înlocui virgula cu un spațiu până când se poate găsi nici mai multe exemple.

Acesta funcționează din cauza unei presupunerea că citatul de deschidere va fi precedată de o virgulă, plus opționale spații (sau vor fi la începutul liniei), iar cotația de închidere va fi urmată de spații opționale, plus o virgulă, sau va fi sfârșitul a liniei.

Sunt sigur că există cazuri în care nu va reuși - dacă cineva „poate posta em, aș fi dornici să-i vadă ...

Publicat 23/06/2009 la 16:25
sursa de către utilizator

voturi
0

Răspunsul meu nu este un regex, dar eu cred că este mai simplu și mai eficient. Schimbarea liniei la o matrice char, apoi du-te prin fiecare char. Țineți evidența sumelor par sau impar citat. În cazul în care suma impar de citate și aveți o virgulă, atunci nu-l adăugați. Ar trebui să arate ceva de genul asta.

public String removeCommaBetweenQuotes(String line){


    int charCount = 0;
    char[] charArray = line.toCharArray();
    StringBuilder newLine = new StringBuilder();

    for(char c : charArray){

        if(c == '"'){
            charCount++;
            newLine.append(c);
        }

        else if(charCount%2 == 1 && c == ','){
            //do nothing
        }

        else{
            newLine.append(c);
        }


    }

    return newLine.toString();


}
Publicat 23/09/2015 la 20:32
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more