2013-04-22 9 views
7

Biorąc pod uwagę ten kod:Wymiana ciąg z wyrażenia regularnego zwraca wymianę dwukrotnie

String replaced = "A".replaceAll(".*", "HI"); 

Dlaczego replaced zawierać ciąg HIHI zamiast HI jak bym się domyślić? Wygląda na to, że ma to coś wspólnego z początkiem linii, ponieważ użycie wzoru daje ^.* wydajność HI, ale nie rozumiem tego.

+0

Możesz użyć '. +', Aby uniemożliwić dopasowanie pustego ciągu znaków ("" "). – brimborium

Odpowiedz

5

myślę to dlatego .* pierwszy dopasowuje cały ciąg, a następnie dopasowuje pusty łańcuch na koniec łańcucha. Oczywiście, ^.* nie będzie pasował do pustego ciągu na końcu "A", więc skończysz z tylko jednym "HI".

5

Spójrz na replaceAll javadoc: Zastępuje każdy podciąg tego łańcucha, który pasuje do danego wyrażenia regularnego z podanym zamiennikiem. Dopasowuje dwa ciągi: "" i "A". Widać to testując

String replaced = "".replaceAll(".*", "HI"); 

co skutkuje singiel „HI” są drukowane

+2

W "A" są dwie pozycje (między literami tak powiedzieć): 0 i 1. Przy 0 "A" mecze, w 1 "" mecze. –

+0

@JoopEggen W każdym razie jest to sprzeczne z intuicją. Jeśli '. *' Jest chciwe, powinno "zjeść" cały ciąg ** zawierający ** pusty ciąg na końcu i jeden raz powrócić do dopasowania. –

+0

dwa puste ciągi '" A ".replaceAll (" "," HI ") == HIAHI' – Kent

0

Metoda znalezienia klasy Matcher znajduje "A" i pusty ciąg po znaku "A", więc istnieją 2 zamienniki.

0

Sposób replaceAll wykonuje regex i parametr zastępczy jako takie jak (read more): -

public String replaceAll(String regex, 
         String replacement) 

W tym przykładzie .* oznacza wyrażenia.

. oznacza dowolny znak (może lub nie może dopasować terminatory linii)

* oznacza zero lub więcej razy (Read More regexp)

Wyjście swojej danego kodu jest prawo. Wyrażenie regularne jest zgodne z * oznacza zero lub więcej razy. I wpływa na wynik.

String replaced = "A".replaceAll(".*", "HI"); 

wyjściowa: - HIHI

nadzieję, że to pomoże.

Powiązane problemy