2016-11-19 2 views
5

У меня есть строка, такая как s = "abc.def..ghi". Я бы хотел заменить сингл '.' с двумя. Однако s.replace(".", "..") дает «abc..def .... ghi». Как я могу получить правильное поведение? Результат, который я ищу, - s = "abc..def..ghi".Замена символов в строке, Java

ответ

6

Заменить точку только тогда, когда он окружен двумя символами

String foo = s.replaceAll("(\\w)\\.(\\w)", "$1..$2"); 

Или, как @Thilo прокомментировал, только если он окружен двух не точками

String foo = s.replaceAll("([^.])\\.([^.])", "$1..$2"); 

И заменить одну точку двумя точками, даже если точка находится в начале/конце t он струна, использовать отрицательный предпросмотр и назад ': (Пример Строка: .abc.def..ghi. будет ..abc..def..ghi..)

String foo = s.replaceAll("(?<!\\.)\\.(?!\\.)", ".."); 
+0

Можете ли вы порекомендовать хороший ресурс «начать работу с регулярным выражением»? – Adam

+2

Я знаю, что http://www.regular-expressions.info/ неплохо, хотя это выглядит не очень красиво. Но вы найдете там очень много. Взгляд/отставание объясняется здесь: http://www.regular-expressions.info/lookaround.html @Adam – baao

-6
s.replace("...",".."); 
s.replace("....",".."); 

В зависимости от входных возможностей ..

+0

Я имею в виду, что он должен использовать их после первого вызова s.replace. Кроме того, ему необходимо наложить некоторый контроль над входным потоком такой строки, иначе парсер в мире не сможет ему помочь. –

+0

Пожалуйста, взгляните на ответ baao и подумайте, хотите ли вы удалить этот ответ. –

3

Если вы не знаете, как сделать это с помощью регулярных выражений затем использовать StringTokenizer разделить строку и снова сцепить с ...

Код:

public static void main(String[] args) { 
    String s = "abc.def..ghi"; 
    StringTokenizer s2 = new StringTokenizer(s, "."); 
    StringBuilder sb = new StringBuilder(); 


    while(s2.hasMoreTokens()) 
    { 
     sb.append(s2.nextToken().toString()); 
     sb.append(".."); 
    } 
    sb.replace(sb.length()-2, sb.length(), ""); // Just delete an extra .. at the end 

    System.out.println(sb.toString()); 

} 

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

В любом случае, я надеюсь, что это поможет.

+0

Я не думаю, что это работает, если у вас есть три последовательных точки (хотя, если быть справедливым, ожидаемое поведение недоказано , Я предполагаю, что вы хотите сохранить их как три точки, а не превращать их в две точки). – Thilo

+0

@Thilo Я пробовал точки со стартом, концом и несколькими точками (> 3) между ними. Это сработало. – SkrewEverything

+0

@Thilo это 'a..b' – SkrewEverything

2

Используйте взгляд обходные:

str = str.replaceAll("(?<!\\.)\\.(?!\\.)", "..")(

Регулярное выражение читает как «точка, не предшествует точка, а не с последующей точкой». Это будет обрабатывать граничные случаи точки, находящейся в начале/конце и/или окруженной буквально любым другим символом.

Поскольку внешний вид не потребляет входные данные, вам не нужно садиться с обратной ссылкой на заменяющий термин.

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