2012-03-29 8 views
4

Ich dachte, dieses relativ kluge Problem mit allen hier zu teilen. Ich versuche, unausgeglichene/ungepaarte doppelte Anführungszeichen aus einer Zeichenfolge zu entfernen.Wie man unausgeglichene/nicht gepreiste Anführungszeichen (in Java) entfernt

Meine Arbeit ist im Gange, ich könnte in der Nähe einer Lösung sein. Aber ich habe noch keine funktionierende Lösung bekommen. Ich bin nicht in der Lage, die ungepaarten/unpartered doppelten Anführungszeichen aus der Zeichenfolge zu löschen.

Beispiel Eingabe

string1=injunct! alter ego." 
string2=successor "alter ego" single employer" "proceeding "citation assets" 

Ausgabe sollte sein

string1=injunct! alter ego. 
string2=successor "alter ego" single employer proceeding "citation assets" 

Dieses Problem ähnlich klingen zu Using Java remove unbalanced/unpartnered parenthesis

Hier ist mein Code so weit (es funktioniert nicht lösche alle unpair-double-quot es)

private String removeUnattachedDoubleQuotes(String stringWithDoubleQuotes) { 
    String firstPass = ""; 

    String openingQuotePattern = "\\\"[a-z0-9\\p{Punct}]"; 
    String closingQuotePattern = "[a-z0-9\\p{Punct}]\\\""; 

    int doubleQuoteLevel = 0; 
    for (int i = 0; i < stringWithDoubleQuotes.length() - 3; i++) { 
     String c = stringWithDoubleQuotes.substring(i, i + 2); 
     if (c.matches(openingQuotePattern)) { 
      doubleQuoteLevel++; 
      firstPass += c; 
     } 
     else if (c.matches(closingQuotePattern)) { 
      if (doubleQuoteLevel > 0) { 
       doubleQuoteLevel--; 
       firstPass += c; 
      } 
     } 
     else { 
      firstPass += c; 
     } 
    } 

    String secondPass = ""; 
    doubleQuoteLevel = 0; 
    for (int i = firstPass.length() - 1; i >= 0; i--) { 
     String c = stringWithDoubleQuotes.substring(i, i + 2); 
     if (c.matches(closingQuotePattern)) { 
      doubleQuoteLevel++; 
      secondPass = c + secondPass; 
     } 
     else if (c.matches(openingQuotePattern)) { 
      if (doubleQuoteLevel > 0) { 
       doubleQuoteLevel--; 
       secondPass = c + secondPass; 
      } 
     } 
     else { 
      secondPass = c + secondPass; 
     } 
    } 

    String result = secondPass; 

    return result; 
} 
+3

Also, was ist Ihre * Frage *? – adarshr

+0

Bitte beachten Sie den fett gedruckten Satz im zweiten Absatz. – Watt

+0

Welche Art von Ausgabe erhalten Sie? – Shaded

Antwort

1

Sie könnte so etwas wie (Perl-Notation) verwenden:

s/("(?=\S)[^"]*(?<=\S)")|"/$1/g; 

, die in Java wäre:

str.replaceAll("(\"(?=\\S)[^\"]*(?<=\\S)\")|\"", "$1"); 
+0

Danke! Aber ich habe Schwierigkeiten, die unpartnered nur doppelte Anführungszeichen zu entfernen. Ich bin bereits in der Lage, alle doppelten Anführungszeichen mit RegEx zu finden. – Watt

+0

Sehen Sie hier http://rubular.com/r/wHkgusUk59, Ihre Lösung wird ALLE doppelten Anführungszeichen entfernen. Ich wollte nur nicht Partnered entfernen, nicht alle Anführungszeichen. Lass es mich wissen, wenn ich falsch liege. – Watt

+1

@S.Singh, nein, es wird nicht alle doppelten Anführungszeichen entfernen ... Warum testest du nicht einmal die komplette Java-Anweisung, die ich für dich geschrieben habe, bevor du Kommentare abgibst, dass es nicht funktioniert? Es funktioniert gut für Ihre Daten, siehe [diese Demo] (http://ideone.com/ZdySA). – Qtax

2

Es wahrscheinlich in einer einzigen Regex getan werden könnte, wenn es ist keine Verschachtelung.
Es gibt ein Konzept von Delimetern grob definiert, und es ist möglich,
diese Regeln zu "bias", um ein besseres Ergebnis zu erhalten.
Es hängt alles davon ab, welche Regeln aufgeführt sind. Diese Regex berücksichtigt
drei mögliche Szenarien in Reihenfolge;

  1. gültiges Paar
  2. Ungültige Pair (mit Vorspannung)
  3. ungültiger Einzel

Es doesen't auch parsen "" jenseits Ende der Zeile. Aber es tut mehrere
Zeilen als eine einzige Zeichenfolge kombiniert. Um das zu ändern, entfernen Sie \n, wo Sie es sehen.


globalen Kontext - roh Fund regex
verkürzt

(?:("[a-zA-Z0-9\p{Punct}][^"\n]*(?<=[a-zA-Z0-9\p{Punct}])")|(?<![a-zA-Z0-9\p{Punct}])"([^"\n]*)"(?![a-zA-Z0-9\p{Punct}])|") 

Ersatz Gruppierung

$1$2 or \1\2 

Expanded roh regex:

(?:       // Grouping 
            // Try to line up a valid pair 
    (        // Capt grp (1) start 
    "        // " 
     [a-zA-Z0-9\p{Punct}]    // 1 of [a-zA-Z0-9\p{Punct}] 
     [^"\n]*       // 0 or more non- [^"\n] characters 
     (?<=[a-zA-Z0-9\p{Punct}])   // 1 of [a-zA-Z0-9\p{Punct}] behind us 
    "        // " 
    )         // End capt grp (1) 

    |        // OR, try to line up an invalid pair 
     (?<![a-zA-Z0-9\p{Punct}])  // Bias, not 1 of [a-zA-Z0-9\p{Punct}] behind us 
    "        // " 
    ( [^"\n]* )      // Capt grp (2) - 0 or more non- [^"\n] characters 
    "        // " 
     (?![a-zA-Z0-9\p{Punct}])  // Bias, not 1 of [a-zA-Z0-9\p{Punct}] ahead of us 

    |        // OR, this single " is considered invalid 
    "        // " 
)        // End Grouping 

Perl Testfall (nicht Java)

$str = ' 
string1=injunct! alter ego." 
string2=successor "alter ego" single employer "a" free" proceeding "citation assets" 
'; 

print "\n'$str'\n"; 

$str =~ s 
/
    (?: 
    (
     "[a-zA-Z0-9\p{Punct}] 
     [^"\n]* 
     (?<=[a-zA-Z0-9\p{Punct}]) 
     " 
    ) 
    | 
     (?<![a-zA-Z0-9\p{Punct}]) 
     " 
    ( [^"\n]* ) 
     " (?![a-zA-Z0-9\p{Punct}]) 
    | 
     " 
) 
/$1$2/xg; 

print "\n'$str'\n"; 

Ausgabe

' 
string1=injunct! alter ego." 
string2=successor "alter ego" single employer "a" free" proceeding "citation assets" 
' 

' 
string1=injunct! alter ego. 
string2=successor "alter ego" single employer "a" free proceeding "citation assets" 
' 
+0

Vielen Dank für eine detaillierte und eine informative Antwort. – Watt

+0

@S. Singh - Vielen Dank für diese interessante Frage. – sln

Verwandte Themen