2015-02-27 13 views
6

Chcę zastąpić ciągi poza cytatami z wykorzystaniem str.replaceAll w Javie, ale zostawić słowa wewnątrz cudzysłowów nietknięteJak wymienić Words Poza cytatów

Gdybym zastąpiony Apple z Pie:

Wejście: Jabłko "Apple Apple Apple"
Pożądany wyjściowa: Pie "Apple Apple Apple"

Uwaga słowa wewnątrz cytatów były nietknięte

Jak to zrobić? Cała pomoc doceniona!

+1

Dlaczego istnieją parens w swoim przykładzie? Czy cytaty będą zawsze zawierać parens? –

+0

Nie, nie zawsze będą widoczne w wierszach –

+1

@ freakshow1217, więc chcesz zmienić tylko pierwsze wystąpienie tego słowa? –

Odpowiedz

5

Szukaj Apple wykorzystaniem lookaheads aby upewnić się, że nie jest w cudzysłowie.?

(?=(([^"]*"){2})*[^"]*$)Apple 

I zastąpić przez:

Pie 

RegEx Demo


Aktualizacja:

podstawie wypowiedzi poniżej można użyć:

Kod:

String str = "Apple \"Apple\""; 
String repl = str.replaceAll("(?=(([^\"]*\"){2})*[^\"]*$)Apple", "Pie"); 
//=> Pie "Apple" "Another Apple Apple Apple" Pie 
+1

To by spowodowało (prawdopodobnie pożądany) efekt uboczny zmiany "CrabApple" na "CrabPie", czyż nie? – childofsoong

+0

można użyć ok granic słów, aby tego uniknąć. – anubhava

+1

Dzięki! To działa dobrze –

0

zakładam to, co chcesz:

String str = "Apple \"Apple\""; 
String replace = str.replaceAll("(?<!\")Apple(?!\")", "Pie"); 

Oto robocza: https://regex101.com/r/kP0oV1/2

+0

Jak tego użyć? –

+0

@ freakshow1217 edytował odpowiedź, wypróbuj –

0

Działa to dla testu:

package mavensandbox; 


import static junit.framework.TestCase.assertEquals; 

public class Test { 

    @org.junit.Test 
    public void testName() throws Exception { 
     String input = "Apple(\"Apple\")"; 
     String output = replaceThoseWithoutQuotes("Apple", "Pie", input); 
     assertEquals("Pie(\"Apple\")", output); 
    } 

    private String replaceThoseWithoutQuotes(String replace, String with, String input) { 
     return input.replaceAll("(?<!\")" + replace + "(?!\")", with); 
    } 
} 

używam tego, co się nazywa negative lookahead and a negative lookbehind . Okazuje się mecze, które nie mają "przed lub za nim Czy to praca dla Ciebie

0

Spróbuj pasujące słowo ze spacjami po niej.

/jabłko \ s/

Następnie zastąp Pie z tej samej spacji po nim.

0

Istnieje również opcja, aby zrobić to bez bardziej skomplikowanego wyrażenia regularnego, jeśli szukasz bardziej iteracyjnego rozwiązania, jeśli jesteś tak skłonny. Możesz podzielić na " i zastąpić indeksy parzyste, a następnie odbudować łańcuch.

String input = "\"unique\" unique unique \"unique\" \"unique\" \"unique\" \"unique\" unique \"unique unique\" unique unique \""; 
    System.out.println(input); 
    String[] split = input.split("\""); 
    for (int i = 0; i < split.length; i = i + 2) { 
     split[i] = split[i].replaceAll("unique", "potato"); 
    } 
    String output = ""; 
    for (String s : split) { 
     output += s + "\""; 
    } 
    System.out.println(output); 

wyjściowa:

"unique" unique unique "unique" "unique" "unique" "unique" unique "unique unique" unique unique " 
"unique" potato potato "unique" "unique" "unique" "unique" potato "unique unique" potato potato "