문자열에 배열의 문자열이 포함되어 있는지 테스트


153

배열의 문자열이 포함되어 있는지 확인하려면 어떻게 문자열을 테스트합니까?

사용하는 대신

if (string.contains(item1) || string.contains(item2) || string.contains(item3))

4
문자열이 배열의 문자열 과 같은지 또는 배열의 문자열이 포함되어 있는지 묻고 있습니까?
Natix

1
배열의 문자열이 입력 문자열의 하위 문자열인지 확인하고 싶습니까? 또는 입력 문자열 배열의 문자열 중 하나 와 같은지 확인하고 싶 습니까? 더 정확할 수 있습니까?
Savino Sguera

1
를 포함하여 줄을 가져 와서 목록에있는 단어가 포함되어 있는지 확인합니다 (문자열 배열로 저장 됨)
arowell

답변:


188

편집 : 다음은 Java 8 Streaming API를 사용한 업데이트입니다. 훨씬 더 깨끗합니다. 여전히 정규 표현식과 결합 할 수 있습니다.

public static boolean stringContainsItemFromList(String inputStr, String[] items) {
    return Arrays.stream(items).parallel().anyMatch(inputStr::contains);
}

또한 입력 유형을 배열 대신 List로 변경하면 사용할 수 있습니다 items.parallelStream().anyMatch(inputStr::contains).

.filter(inputStr::contains).findAny()일치하는 문자열을 반환하려는 경우 에도 사용할 수 있습니다 .


약간 날짜가 적힌 원래 답변 :

다음은 (VERY BASIC) 정적 메소드입니다. 비교 문자열에서는 대소 문자를 구분합니다. 원시적 그 사례를 구분을 할 방법은 전화를하는 것 toLowerCase()또는 toUpperCase()모두 입력 및 테스트 문자열을.

이보다 복잡한 작업을 수행해야하는 경우 Pattern and Matcher 클래스를 보고 정규 표현식을 수행하는 방법을 배우는 것이 좋습니다 . 일단 이해하면 해당 클래스 또는 String.matches()도우미 메소드를 사용할 수 있습니다 .

public static boolean stringContainsItemFromList(String inputStr, String[] items)
{
    for(int i =0; i < items.length; i++)
    {
        if(inputStr.contains(items[i]))
        {
            return true;
        }
    }
    return false;
}

1
정규 표현식을 사용하는 방법은 @gnomed
Praneeth

첫 번째 구현 사례를 어떻게 민감하게 만들 수 있습니까?
thanos.a

구현은 이미 대소 문자를 구분합니다. 또한 답변의 맨 아래 단락에서 대소 문자를 구분하지 않는 방법에 대한 지침도 있습니다.
gnomed

52
import org.apache.commons.lang.StringUtils;

문자열 유틸리티

사용하다:

StringUtils.indexOfAny(inputString, new String[]{item1, item2, item3})

찾은 문자열의 색인을 찾거나없는 경우 -1을 반환합니다.


7
JFI :이 구현이 inputString을 한 번만 반복하기를 원했지만 StringUtils의 코드를 보았지만 슬프게도 기본 indexOf의 N 호출을하고 있습니다.
alfonx

아마도 commons3에서 구현이 더 좋습니다!
renanleandrof

1
아니, 여전히 org.apache.commons.lang3.StringUtils의 문자열을 반복합니다 : for (int i = 0; i <searchStrs.length; i ++) {CharSequenceUtils.indexOf (str, search, 0); ....
alfonx

이것은 배열에서 찾은 문자열의 인덱스를 반환하지 않고 문자열이 찾은 위치의 인덱스 만 반환합니다.
명왕성

33

다음 과 같이 String # matches 메소드를 사용할 수 있습니다 .

System.out.printf("Matches - [%s]%n", string.matches("^.*?(item1|item2|item3).*$"));

16

가장 쉬운 방법은 아마도 배열을 java.util.ArrayList로 변환하는 것입니다. 일단 배열 목록에 있으면 contains 메소드를 쉽게 활용할 수 있습니다.

public static boolean bagOfWords(String str)
{
    String[] words = {"word1", "word2", "word3", "word4", "word5"};  
    return (Arrays.asList(words).contains(str));
}

70
이것은 올바르지 않습니다. 경우 영업 이익이 요구하고 string있는 포함 String배열들, 어떤하지 않을 경우 String배열들 포함 string.
Beau Grantham

3
@BeauGrantham 나도 이것을 생각하고 있었지만 OP가 .equals()게시물에서 사용 하고있어 매우 혼란 스럽습니다. 나는 그들이 질문을 편집해야한다고 생각한다
무시

@BeauGrantham Man 나는 맹세 할 수 없어서 문제를 이해했다. 아마도 질문이 좀 더 명확 해져야할까요?
Roy Kachouh 2012 년

1
아니요,이 종류의 역 방향은 작동하지 않습니다. 문자열에 주어진 값 중 하나가 포함되어 있는지 확인하고 제공된 값에 문자열이 포함되어 있는지 여부를 확인해야합니다.
Vladimir Stazhilov

2
질문은 정반대입니다
Stéphane GRILLON

16

당신이 사용하는 경우 자바 8 위 또는, 당신은 신뢰할 수있는 스트림 API 와 같은 일을 :

public static boolean containsItemFromArray(String inputString, String[] items) {
    // Convert the array of String items as a Stream
    // For each element of the Stream call inputString.contains(element)
    // If you have any match returns true, false otherwise
    return Arrays.stream(items).anyMatch(inputString::contains);
}

String테스트 할 큰 배열이 있다고 가정하면을 호출하여 검색을 병렬로 시작할 수도 parallel()있습니다. 그러면 코드는 다음과 같습니다.

return Arrays.stream(items).parallel().anyMatch(inputString::contains); 

이상한 점은 문자열 목록에 두 개의 항목이 있으며 '병렬'을 사용할 때 올바른 결과를 반환하지 않는다는 것을 알았습니다. (값을 포함하더라도).
CharlesC

@ Charles.C 그것은 내 편에서 재현 할 수없는 이상합니다.
Nicolas Filotto

입력 문자열이 길지 않으면 (~ 500 자) 스트림을 병렬 처리하는 것이 차선책이라고 확신합니다. 대신 배열이 크면 배열을 분할하고 각 배열을 병렬로 실행하는 것이 좋습니다.
lifesoordinary

2

여기에 하나의 해결책이 있습니다.

public static boolean containsAny(String str, String[] words)
{
   boolean bResult=false; // will be set, if any of the words are found
   //String[] words = {"word1", "word2", "word3", "word4", "word5"};

   List<String> list = Arrays.asList(words);
   for (String word: list ) {
       boolean bFound = str.contains(word);
       if (bFound) {bResult=bFound; break;}
   }
   return bResult;
}


1

더 groovyesque 접근 방식은 metaClass 와 함께 inject 를 사용 하는 것입니다 .

나는 말하고 싶습니다 :

String myInput="This string is FORBIDDEN"
myInput.containsAny(["FORBIDDEN","NOT_ALLOWED"]) //=>true

그리고 방법은 다음과 같습니다.

myInput.metaClass.containsAny={List<String> notAllowedTerms->
   notAllowedTerms?.inject(false,{found,term->found || delegate.contains(term)})
}

향후 String 변수에 대해 containsAny 가 필요 하면 객체 대신 클래스에 메소드를 추가하십시오.

String.metaClass.containsAny={notAllowedTerms->
   notAllowedTerms?.inject(false,{found,term->found || delegate.contains(term)})
}


0

대소 문자를 구분하지 않는 경우 패턴을 사용하십시오.

Pattern pattern = Pattern.compile("\\bitem1 |item2\\b",java.util.regex.Pattern.CASE_INSENSITIVE);

    Matcher matcher = pattern.matcher(input);
    if(matcher.find() ){ 

}

0

전체 단어 를 다루는 경우 대소 문자를 구분 하지 않고도이 작업을 수행 할 수 있습니다 .

private boolean containsKeyword(String line, String[] keywords)
{
    String[] inputWords = line.split(" ");

    for (String inputWord : inputWords)
    {
        for (String keyword : keywords)
        {
            if (inputWord.equalsIgnoreCase(keyword))
            {
                return true;
            }
        }
    }

    return false;
}

0

우리는 또한 이렇게 할 수 있습니다 :

if (string.matches("^.*?((?i)item1|item2|item3).*$"))
(?i): used for case insensitive
.*? & .*$: used for checking whether it is present anywhere in between the string.

-3

Strings 가 검색하는 배열 이라고 가정하면 아래에서 작동합니다 .

Arrays.binarySearch(Strings,"mykeytosearch",mysearchComparator);

여기서 mykeytosearch는 배열 내에 존재하는지 테스트하려는 문자열입니다. mysearchComparator-문자열을 비교하는 데 사용되는 비교기입니다.

자세한 내용은 Arrays.binarySearch 를 참조하십시오.


2
binarySearch는 자연적으로 또는 주어진 비교기 (주어진 경우)에 의해 정렬 된 배열에서만 작동합니다.
Natix

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.