2010-02-16 10 views
432

Mam dwa String s, str1 i str2. Jak sprawdzić, czy str2 jest zawarty w , ignorując przypadek?W języku Java, w jaki sposób sprawdzić, czy ciąg zawiera podłańcuch (ignorowanie przypadku)?

+1

Zarówno indexOf, jak i zawiera znak go po znaku, więc jeśli potrzebujesz szybszego wyszukiwania ciągów znaków (które możesz uzyskać), musisz zaimplementować jeden z wielu opublikowanych algorytmów. –

+2

Mam to samo pytanie tutaj jest odpowiedź :) http: // stackoverflow.com/a/86832/621951 –

Odpowiedz

878
str1.toLowerCase().contains(str2.toLowerCase()) 
+4

z jakiegoś powodu dostaję fałszywy, gdy dzwonię "2014-03-25T17: 55: 00" .contains ("T") –

+3

Czy istnieje funkcja, która zwraca i pozycja, gdzie wystąpił, który zawiera (str2)? – RadijatoR

+6

@RadijatoR Tak, nazywa się indexOf, jak 'int pos = str1.indexOf (str2)' lub wielkość liter nie ma znaczenia jako 'int pos = str1.toLowerCase(). IndexOf (str2.toLowerCase())' –

20

Można użyć metody toLowerCase():

public boolean contains(String haystack, String needle) { 
    haystack = haystack == null ? "" : haystack; 
    needle = needle == null ? "" : needle; 

    // Works, but is not the best. 
    //return haystack.toLowerCase().indexOf(needle.toLowerCase()) > -1 

    return haystack.toLowerCase().contains(needle.toLowerCase()) 
} 

następnie połączyć go za pomocą:

if(contains(str1, str2)) { 
    System.out.println("Found " + str2 + " within " + str1 + "."); 
} 

Zauważ, że tworząc swoją własną metodę, można je ponownie wykorzystać. Następnie, gdy ktoś zauważy, że powinieneś użyć contains zamiast indexOf, musisz zmienić tylko jeden wiersz kodu.

+5

Pamiętaj, aby dodać Javadoc do zachowania podczas przekazywania obiektów o wartości NULL. –

+0

Rozwiązanie Pomaga :) – akash89

6

Chciałbym użyć kombinacji metody contains i metody toUpper, które są częścią klasy String. Przykładem jest poniżej:

String string1 = "AAABBBCCC"; 
String string2 = "DDDEEEFFF"; 
String searchForThis = "AABB"; 

System.out.println("Search1="+string1.toUpperCase().contains(searchForThis.toUpperCase())); 

System.out.println("Search2="+string2.toUpperCase().contains(searchForThis.toUpperCase())); 

ten powróci:

search1 = true
Search2 = false

+4

Nie działa. Niektóre dziwne znaki międzynarodowe są konwertowane na wiele znaków po konwersji na małe/duże litery. Na przykład: '" ß ".toUpperCase(). Equals (" SS ")' – Simon

+1

To by się stało. Tak powstaje podwójne słowo po niemiecku. –

111

Jak o matches()?

String string = "Madam, I am Adam"; 

// Starts with 
boolean b = string.startsWith("Mad"); // true 

// Ends with 
b = string.endsWith("dam");    // true 

// Anywhere 
b = string.indexOf("I am") >= 0;  // true 

// To ignore case, regular expressions must be used 

// Starts with 
b = string.matches("(?i)mad.*"); 

// Ends with 
b = string.matches("(?i).*adam"); 

// Anywhere 
b = string.matches("(?i).*i am.*"); 
+12

Twój przykład "indexOf" powinien używać> = 0, nie> 0, ponieważ 0 jest poprawne, jeśli podciągi występują na początku łańcucha. (Nie w twoim przykładzie, ale może w innych przypadkach.) Dodano tę odpowiedź, ponieważ ludzie wciąż szukają i znajdują tę odpowiedź. –

29

Jeśli jesteś w stanie wykorzystać org.apache.commons.lang.StringUtils, proponuję przy użyciu następujących:

String container = "aBcDeFg"; 
String content = "dE"; 
boolean containerContainsContent = StringUtils.containsIgnoreCase(container, content); 
9

I sprzyjać również rozwiązanie regex. Kod będzie znacznie czystszy. Wahałbym się użyć do LowerCase() w sytuacjach, w których wiedziałem, że struny będą duże, ponieważ ciągi są niezmienne i musiałyby być skopiowane. Również rozwiązanie matches() może być mylące, ponieważ jako argument przyjmuje wyrażenie regularne (szukanie "Need $ le" jest problematyczne).

Opierając się na niektórych z powyższych przykładów:

public boolean containsIgnoreCase(String haystack, String needle) { 
    if(needle.equals("")) 
    return true; 
    if(haystack == null || needle == null || haystack .equals("")) 
    return false; 

    Pattern p = Pattern.compile(needle,Pattern.CASE_INSENSITIVE+Pattern.LITERAL); 
    Matcher m = p.matcher(haystack); 
    return m.find(); 
} 

example call: 

String needle = "Need$le"; 
String haystack = "This is a haystack that might have a need$le in it."; 
if(containsIgnoreCase(haystack, needle)) { 
    System.out.println("Found " + needle + " within " + haystack + "."); 
} 

(Uwaga:. Może chcesz obsługiwać NULL i pustych ciągów różnie w zależności od potrzeb Myślę, że sposób mam to bliżej specyfikacji Java w przypadku ciągów znaków.)

Rozwiązania o ograniczonej szybkości mogą obejmować iterację poprzez znak stogu siana przez postać szukającą pierwszego znaku igły. Kiedy pierwszy znak zostanie dopasowany (przypadek nieistniejący), zacznij powtarzać igłę po znaku, szukając odpowiedniego znaku w stogu siana i zwracając "true", jeśli wszystkie postacie zostaną dopasowane. Jeśli napotkany zostanie nie dopasowany znak, wznów iterację za pośrednictwem stogu siana na następnym znaku, zwracając "false", jeśli osiągnięta zostanie pozycja> haystack.length() - needle.length().

+2

Chciałbym zrobić: 'Pattern.CASE_INSENSITIVE | Pattern.LITERAL' –

+0

@mikejones Jak mogę to sprawdzić tylko dla słów? Rozważmy przypadek poniżej: 1) "To jest stóg siana, który może potrzebować $ le."; 2) "To jest stóg siana, który może potrzebować mniej $."; Chcę, aby dopasować tylko przypadek 1, ponieważ w tym przypadku potrzeba $ le jest obecna jako słowo. Nie chcę, aby druga skrzynia była dopasowana. Jak mogę to osiągnąć? –

Powiązane problemy