2016-07-06 52 views
5

Mam ArrayList<String>, który sprawdzam, aby znaleźć poprawny indeks z podanym łańcuchem. Zasadniczo, biorąc pod uwagę String, program powinien przeszukać listę i znaleźć indeks, w którym pasuje całe słowo. Na przykład:Java dopasowuje całe słowo w łańcuchu

ArrayList<String> foo = new ArrayList<String>(); 
foo.add("AAAB_11232016.txt"); 
foo.add("BBB_12252016.txt"); 
foo.add("AAA_09212017.txt"); 

Więc jeśli dam String AAA, powinienem wrócić indeks 2 (ostatni). Więc nie mogę użyć metody , ponieważ dałoby mi to powrót do indeksu 0.

Próbowałem z tym kodem:

String str = "AAA"; 
String pattern = "\\b" + str + "\\b"; 
Pattern p = Pattern.compile(pattern); 

for(int i = 0; i < foo.size(); i++) { 
    // Check each entry of list to find the correct value 
    Matcher match = p.matcher(foo.get(i)); 

    if(match.find() == true) { 
     return i; 
    } 
} 

Niestety, nigdy nie osiągnie tego kodu instrukcji wewnątrz pętli if. Nie jestem pewien, co robię źle.

Uwaga: Powinno to również działać, gdy szukałem AAA_0921, pełnej nazwy AAA_09212017.txt lub dowolnej części String, która jest dla niego unikalna.

+2

'_' jest uważana za słowo character..so przyzwyczajenie działać jako granicy słowa .. – rock321987

+0

Ooh, ja nie wiedziałem o tym. Zajrzę do innego wyrażenia. – syy

+0

Nie masz na myśli 'return i;'? – 4castle

Odpowiedz

5

Ponieważ granica słowo nie pasuje między char słowo i podkreślenia trzeba

String pattern = "(?<=_|\\b)" + str + "(?=_|\\b)"; 

Tutaj (?<=_|\b) pozytywny lookbehind wymaga granicę słowa lub znaku podkreślenia do stawienia się przed str, a pozytywny uprzedzona (?=_|\b) wymaga użycia podkreślenie lub granica słowa wyświetlana zaraz po str.

Zobacz this regex demo.

Jeśli słowo może mieć specjalne znaki wewnątrz, można użyć bardziej prosta słowo granicę:

"(?<![^\\W_])" + Pattern.quote(str) + "(?![^\\W_])" 

Tutaj ujemny lookbehind (?<![^\\W_]) nie mecz, jeśli istnieje znak słowo wyjątkiem podkreślenie ([^...] to negowana klasa znaków, która pasuje do dowolnego znaku innego niż znaki, zakresy itp. zdefiniowanego w tej klasie, w związku z czym pasuje do wszystkich znaków innych niż niesformatowane char \W i _), a także do ujemnego wyniku wyprzedzającego (?![^\W_]) kończy się niepowodzeniem, jeśli występuje słowo char z wyjątkiem podkreślenia po str.

Należy zauważyć, że drugi przykład ma cytowany ciąg wyszukiwania, dzięki czemu nawet AA.A_str.txt może być dobrze dopasowany do AA.A.

Zobacz another regex demo

+0

Dziękuję bardzo! To sprawiło, że działało. Czy możesz wyjaśnić różne części wyrażenia? Jestem całkiem nowy w 'regex'. jeśli nie, to w porządku, mogę to sprawdzić. – syy

+1

@Flow Jednym świetnym narzędziem jest [regex101.com] (http://www.regex101.com). Jeśli spojrzysz w prawy górny panel, wyjaśnisz to, co je wypiszesz. To prawda, nie obsługuje regex Java, ale zwykle jest wystarczająco blisko PCRE. – 4castle

+2

Walczę z moim synem o laptopa w przedziale pociągu, a spróbuję oczywiście :) –