2016-04-14 8 views
1

Ich ersetze Fragezeichen in einer Zeichenfolge mit anderen Werten.Java Ersetzen von Questionmarks, die nicht von Anführungszeichen umgeben sind

Beispiel:

String: "XYZ(?,?,?)" 

Values: [1, 'Text', 0.5] 

Result: XYZ(1,'Text', 0.5) 

Mein Preudo-Code:

String s = "XYZ(?,?,?)"; 
for(int i = 0; i < array.lengh; i++){ 
    s = s.replaceFirst("\\?",array[i]); 
} 

Normalerweise gut das funktioniert. Aber manchmal habe ich ein Fragezeichen in den Werten wie: Werte: [1,'Question?',0.5]. Dann ist mein Ergebnis: XYZ(1,'Question0.5', ?). Dies liegt daran, dass die Funktion das Fragezeichen des Textes ersetzt, der eine Iteration früher ersetzt wurde.

Wie kann ich der Funktion sagen, nur Fragezeichen zu ersetzen, die nicht in Anführungszeichen eingeschlossen sind? Was ist der richtige Regex?

+0

Sollte Ihr Pseudo-Code sein 's = s.replaceFirst (regex, Ersatz)' ;? –

Antwort

2

Wenn Sie Regex nicht verwenden oder ersetzen müssen, wie wäre es damit?

String s = "XYZ(?,?,?)"; 
String[] tokens = s.split("\\?"); 
s = ""; 
for(int i = 0; i < array.length; i++){ 
    s += tokens[i] + array[i]; 
} 
s += tokens[array.length]; 

(Edits:? Entkommen in regex, Länge an, ein Teil nach dem letzten Einsetzen müssen)

Wenn es können zusätzliche Frage Marken sein, ist, dass mehr von dann als die Anzahl der Werte zu sein eingefügt, und Sie möchten die überzähligen zu halten und jeden Text nach ihnen wie der OP-Code hat, die split begrenzen:

String[] tokens = s.split("\\?", array.length+1); 

Wenn die Anzahl der Fragezeichen oder die Gesamtgröße des Ergebnisses (die Vorlage Zeichenfolge plus die Insertionen) ist groß, wiederholte String-Verkettung perf Orms schlecht; verwenden StringBuilder statt:

StringBuilder b = new StringBuilder (s.length()+estimated_expansion); 
// this estimate doesn't have to be correct, but if it is high enough 
// without being *much* too high performance is optimized 
for(int i = 0; i < array.length; i++){ 
    b.append(tokens[i]).append(array[i]); 
} 
s = b.append(tokens[array.length]).toString(); 
+0

Dies wird zu dem gleichen Problem führen, wenn eines der Fragezeichen von einem Zitat umgeben ist, so dass das OP-Problem nicht löst . –

+0

@chsdk nein, es wird nicht das gleiche Problem verursachen. Dies ist eine gültige Lösung. –

+0

@ UtkuÖzdemir Ach ja, du hast Recht, mein Schlechter, ich habe den Punkt verpasst, dass die Saite einmal gespalten wird, dann wird sie fein ersetzt. –

0

Sie diese Regex verwenden:

String regex = "\\?(?=[^']+$)"; 

Die Idee ist, wenn Sie s.replaceFirst(regex, str) nennen, die erste "?" nicht durch ein Zitat sein kann, nicht in Anführungszeichen zu folgen.

+0

jetzt kein Fragezeichen ist ersetzt – Daniel

+0

@Daniel oops, ich hatte einen Tippfehler gemacht, jetzt sollte es funktionieren – Maljam

1

Sie können alle Fragezeichen zuerst durch %s ersetzen und dann String.format(input, args...) verwenden. Etwas wie folgt aus:

Object[] array = {1, "Test", 0.5}; 
String s = "XYZ(?,?,?)"; 

String output = String.format(s.replace("?", "%s"), array); 
System.out.println(output); 

geben Sie diese Ausgabe:

XYZ (1, Test, 0,5)

auch bemerken, dass in Ihrer Frage, Ihr s.replaceFirst("\\?",array[i]); Anruf unwirksam, weil in Java-Strings unveränderlich sind und alle Operationen auf string, wie replace, einen neuen String zurückgeben und Sie den zurückgegebenen String verwenden sollten.

Eine andere Anmerkung: Zeichenfolgen sollten in doppelten Anführungszeichen und nicht in einfachen Anführungszeichen stehen.

0

Wie über einen einfacheren Ansatz, wie unten codiert?

public class Replacer { 
    static String replace(String s, String[] values) { 
     StringBuffer sb = new StringBuffer(); 
     for (int i = 0, j = 0; i < s.length(); i ++) { 
      char c = s.charAt(i); 
      if (c != '?') 
       sb.append(c); 
      else 
       sb.append(values[j++]); 
     } 
     return sb.toString(); 
    } 

    public static void main(String[] args) { 
     System.out.println(replace("XYZ(?, ?, ?)", new String[]{"1", "Question?", "0.5"})); 
     System.out.println(replace("XYZ(?, ?, ?)", new String[]{"foo", "bar", "baz"})); 
    } 
} 

Diese Drucke:

XYZ(1, Question?, 0.5) 
XYZ(foo, bar, baz) 
Verwandte Themen