2016-04-14 4 views
1

Я заменяю вопросительные знаки в строке с разными значениями.Java Replace Вопросительные знаки, не окруженные кавычками

Пример:

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

Values: [1, 'Text', 0.5] 

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

Мои Preudo-код:

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

Обычно это работает хорошо. Но иногда у меня есть знак вопроса в значениях, таких как: Значения: [1,'Question?',0.5]. Тогда мой результат: XYZ(1,'Question0.5', ?). Это связано с тем, что функция заменяет знак вопроса для текста, замененного на одну итерацию ранее.

Как я могу сказать функции заменить только вопросительные знаки, которые не окружены кавычками? Правильное регулярное выражение?

+0

должен быть ваш псевдо-код 's = s.replaceFirst (регулярное выражение, замена)' ;? –

ответ

2

Если вам не нужно использовать регулярное выражение или заменить, как насчет этого?

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]; 

(редактирует: бежать в регулярных выражениях, длина имеет в, необходимо часть после последнего введения)

Если может быть дополнительные знаки вопроса, то есть больше, то чем число значений будет вставлено, и вы хотите сохранить лишние и любой текст после них, как код OP делает, ограничить split:

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

Если число знаков вопроса или общий размер результата (строка шаблона плюс вставки) большая, повторная конкатенация строк perf ормы плохо; использовать StringBuilder вместо:

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

, это приведет к той же проблеме, если какой-либо из вопросников будет окружен цитатой, так что это не решит проблему OP , –

+0

@chsdk нет, это не вызовет такой же проблемы. Это допустимое решение. –

+0

@ UtkuÖzdemir Ах, да, вы правы, мой плохой, я пропустил мысль о том, что строка будет разделена один раз, после чего она будет полностью заменена. –

0

Вы могли бы использовать это регулярное выражение:

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

Идея заключается в том, когда вы звоните s.replaceFirst(regex, str), первый "?" не последует цитата не может быть внутри кавычек.

+0

сейчас вопрос не заменен – Daniel

+0

@ Daniel oops, я сделал опечатку, теперь он должен работать – Maljam

1

Сначала вы можете заменить все вопросительные знаки %s, а затем использовать String.format(input, args...). Что-то вроде этого:

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

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

даст вам этот вывод:

XYZ (1, Test, 0,5)

Кроме того, обратите внимание, что в вашем вопросе, ваш s.replaceFirst("\\?",array[i]); вызов неэффективен, потому что в Java строки неизменяемы и все операции над строкой, такие как replace, возвращают новую String, и вы должны использовать возвращенную.

Еще одно примечание: строки должны быть в двойных кавычках, а не одинарные кавычки.

0

Как насчет более простой подход, как кодируются ниже?

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"})); 
    } 
} 

Это печатает:

XYZ(1, Question?, 0.5) 
XYZ(foo, bar, baz) 
Смежные вопросы