2009-08-05 4 views
51

Используя Java, я хочу пройти строки текста и заменить все символы амперсанда (&) с ссылкой на объект XML &.Как заменить символ в строке на Java?

Я просматриваю строки текста, а затем каждое слово в тексте со Сканером. Затем я использую CharacterIterator для повторения над каждым символом слова. Однако, как я могу заменить символ? Во-первых, строки являются неизменяемыми объектами. Во-вторых, я хочу заменить символ (&) на несколько символов (amp&;). Как мне подойти к этому?

CharacterIterator it = new StringCharacterIterator(token); 
for(char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) { 
     if(ch == '&') { 

     } 
} 

ответ

100

Попробуйте вместо этого использовать String.replaceAll().

String my_new_str = my_str.replaceAll("&", "&"); 
+61

Будьте осторожны с replaceAll , потому что он использует свой первый аргумент как регулярное выражение. То есть «h.e.l.l.o» .replaceAll («.», «,») даст вам «,,,,,,,,,»! В Java 1.5 существует новый метод String.replace (CharSequence, CharSequence), который делает что-то подобное, но не интерпретирует первый аргумент как регулярное выражение. –

14
StringBuilder s = new StringBuilder(token.length()); 

CharacterIterator it = new StringCharacterIterator(token); 
for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) { 
    switch (ch) { 
     case '&': 
      s.append("&"); 
      break; 
     case '<': 
      s.append("&lt;"); 
      break; 
     case '>': 
      s.append("&gt;"); 
      break; 
     default: 
      s.append(ch); 
      break; 
    } 
} 

token = s.toString(); 
+1

В этом случае вам не нужен StringBuffer. –

+1

Использование String вместо этого приведет к созданию временного объекта String для каждой итерации. Я не уверен, какую альтернативу вы предложили бы. –

+0

string.replaceAll? – IRBMe

4

Просто создайте строку, содержащую все данные о которых идет речь, а затем использовать String.replaceAll(), как показано ниже.

String result = yourString.replaceAll("&", "&amp;"); 
+0

Если данные слишком велики, создание одной строки, состоящей из всех данных, может оказаться невыгодным. Мы также можем делать строки за строкой. – Bhushan

+0

Использование replaceAll в этом случае НЕПРАВИЛЬНО! Если возможно, всегда используйте вместо replaceAll замену. Он более эффективен и менее подвержен ошибкам. –

0

Посмотрите на метод this.

+0

Обратите внимание на заменяемые типы параметров (char, char) - это односимвольная замена. – Amber

+0

Да, да, исправлено сразу после публикации. – IRBMe

+0

Я думаю, вам нужно отступом [1] на вашей ссылке, чтобы заставить его привязать ... может быть? –

0

Если вы используете Spring, вы можете просто позвонить HtmlUtils.htmlEscape(String input), который будет обрабатывать перевод '&' '' & '.

+0

Это рискованно, потому что HTML имеет гораздо больше сущностей, чем чистый XML. –

1

Escaping strings can be tricky - особенно если вы хотите использовать unicode. Я полагаю, что XML - один из самых простых форматов/языков для выхода, но все же. Я бы порекомендовал взглянуть на класс StringEscapeUtils в Apache Commons Lang и его удобный метод escapeXml.

7

Вы также можете проверить, чтобы убедиться, что вы не заменили замещение, которое уже было заменено. Для этого вы можете использовать регулярное выражение с отрицательным обращением.

Например:

String str = "sdasdasa&amp;adas&dasdasa";
str = str.replaceAll("&(?!amp;)", "&amp;");

Это приведет к строке "sdasdasa & АДАС & dasdasa".

Образец регулярного выражения «& (?! Amp;)» в основном говорит: сопоставить любое вхождение «&», за которым не следует «amp;».

82

Ответ прост:

token = token.replace("&", "&amp;"); 

Несмотря на название, по сравнению с replaceAll, заменить это сделать replaceAll, он просто не использует регулярное выражение, которое, кажется, в порядке здесь (оба производительность и перспектива хорошей практики - не используйте регулярные выражения случайно, поскольку они имеют особые требования к персонажам, на которые вы не будете обращать внимания).

Ответ Шона Брайта, вероятно, так же хорош, как стоит подумать с точки зрения производительности, если у вас нет какого-либо дополнительного целевого требования при тестировании производительности и производительности, если вы уже знаете, что этот код является горячей точкой для производительности, если это ваш вопрос исходит из. Это, конечно, не заслуживает нисходящих спусков. Просто используйте StringBuilder вместо StringBuffer, если вам не нужна синхронизация.

Это, как говорится, есть несколько более глубокая потенциальная проблема. Экранирование символов - известная проблема, которую адресуют множество библиотек. Возможно, вы захотите рассмотреть вопрос об упаковке данных в разделе CDATA в XML, или вы можете предпочесть использовать библиотеку XML (включая ту, которая поставляется вместе с JDK), чтобы фактически генерировать XML правильно (чтобы он обрабатывал кодировку).

Apache также имеет escaping library как часть Commons Lang.

0
//I think this will work, you don't have to replace on the even, it's just an example. 

public void emphasize(String phrase, char ch) 
    { 
     char phraseArray[] = phrase.toCharArray(); 
     for(int i=0; i< phrase.length(); i++) 
     { 
      if(i%2==0)// even number 
      { 
       String value = Character.toString(phraseArray[i]); 
       value = value.replace(value,"*"); 
       phraseArray[i] = value.charAt(0); 
      } 
     } 
    } 
1

Попробуйте этот код. Вы можете заменить любой символ другим заданным символом. Здесь я попытался заменить букву 'а' с "-" символ для поддавки строки "abcdeaa"

Выход -> _ bcdef__

public class Replace { 

    public static void replaceChar(String str,String target){ 
     String result = str.replaceAll(target, "_"); 
     System.out.println(result); 
    } 

    public static void main(String[] args) { 
     replaceChar("abcdefaa","a"); 
    } 

} 
Смежные вопросы