대소 문자를 구분하지 않는 PHP in_array 함수


131

in_array함수를 사용할 때 대소 문자를 구분하지 않는 비교가 가능 합니까?

따라서 다음과 같은 소스 배열을 사용하십시오.

$a= array(
 'one',
 'two',
 'three',
 'four'
);

다음 조회는 모두 true를 반환합니다.

in_array('one', $a);
in_array('two', $a);
in_array('ONE', $a);
in_array('fOUr', $a);

어떤 기능 또는 일련의 기능이 동일합니까? 나는 in_array그 자체가 이것을 할 수 있다고 생각하지 않습니다 .

답변:


101

당신은 사용할 수 있습니다 preg_grep():

$a= array(
 'one',
 'two',
 'three',
 'four'
);

print_r( preg_grep( "/ONe/i" , $a ) );

37
정규 표현식을 사용하는 것은 속도가 느릴 수 있으므로 좋은 해결책이 아닙니다. 어쩌면 array_map이 더 빠를 수 있습니다
phil-opp

5
in_array를 드롭 인 대체로 만들고 부울을 반환하면 다음과 같이됩니다 count(preg_grep('/^'.preg_quote($needle).'/$',$a)>0). 그렇다면 그렇게 우아하지는 않습니다. (부분 일치를 원하지 않으면 ^ 및 $ 문자가 필요합니다.) 실제로 일치하는 항목을 반환하려면이 솔루션이 마음에 듭니다.
대런 쿡

2
마지막 주석에는 구문 오류가 있습니다. 대신 / $는 $ / 여야합니다.
Gogowitsch

1
@DarrenCook까지 난 빈 배열로도 일 (BOOL) preg_grep ( '/ ^'preg_quote ($ 바늘) '$ /', $ a는..), false로 캐스팅 할 것 부울 캐스트를 알고
arraintxo

8
더 쉬운 방법은 소문자로 변환하는 것 같습니다.
Joshua Dance

229

분명한 것은 검색어를 소문자로 변환하는 것입니다.

if (in_array(strtolower($word), $array)) { 
  ...

물론 배열에 대문자가 있으면 먼저이 작업을 수행해야합니다.

$search_array = array_map('strtolower', $array);

검색하십시오. strtolower검색 할 때마다 전체 배열을 수행 할 필요는 없습니다 .

그러나 배열 검색은 선형입니다. 배열이 크거나이 작업을 많이 수행하려는 경우 훨씬 빠른 액세스 가 가능하므로 검색어를 배열의 키에 배치하는 것이 좋습니다 .

$search_array = array_combine(array_map('strtolower', $a), $a);

그때

if ($search_array[strtolower($word)]) { 
  ...

여기서 유일한 문제는 배열 키가 고유해야하기 때문에 충돌이있는 경우 (예 : "하나"와 "하나") 하나를 제외한 모든 것을 잃게됩니다.


23
이것이 정답입니다. 정규 표현식을 추가하면 때로는 두 가지 문제가 발생합니다.
Joshua Dance

1
여기서 array_flip이 array_combine 대신 더 빠른 솔루션이 아닌가? $ search_array = array_flip (array_map ( 'strtolower', $ a));
jakub_jo

한 줄 : in_array (strtolower ($ word), array_map ( 'strtolower', $ array))
Andrew

1
야마모토 @ 아키라- "수정 구문"편집 이란 무엇입니까? 여기에서 코드를 수정할 수 없습니다. 나는 그것을 롤백했다.
Funk Forty Niner

또는 array_change_key_case ()를 사용하십시오. secure.php.net/manual/en/function.array-change-key-case.php
boctulus

113
function in_arrayi($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack));
}

에서 문서


3
다른 곳에서 얻은 코드 (또는 실제로 무엇이든)를 인용 인용해야합니다.
cletus

3
분명해 지려면 비판이 아닙니다. 단지 제안 (그리고 내 의견 만, 공식은 없음). :) 적어도 페이지에서 코드 스 니펫을 복사하면 인용을 차단합니다.
cletus

3
또한 코드 블록을 사용하면 '코드'이므로 더 잘 설명 할 수 있습니다. 인용을 인용하면 제대로 형식을 지정할 수 없습니다.
Tyler Carter

>모든 줄 에 추가 하기 위해 실제 버튼을 사용한 후에 올바르게 작동합니다. 방금 >첫 줄 에 수동으로 넣는 데 익숙합니다 .
Tyler Carter

나는 ctrl-Q를 사용하여 익숙해졌습니다. 어떤 이유로 인해 줄을 감싸기 때문에 코드 블록에 한 가지 문제가 있습니다. 이유를 묻지 마십시오. 그러나 수정하거나 >각 줄의 시작 부분에 수동으로 넣을 수 있습니다 .
cletus

50
function in_arrayi($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack));
}

출처 : php.net in_array 매뉴얼 페이지.


배열에 무엇이 있는지 아는 경우 array_map을 생략 할 수 있습니다. 그러나 이것은 좋은 예입니다.
Don

2
나는 실제로했다. 모든 호출에서 배열을 매핑하는 것은 우스운 일입니다.
cletus

또한 (Chcha와 같은) 문서에서 직접 가져 온다고 가정하면 인용을 차단하는 것이 좋습니다.
cletus

10

in_array를 사용하고 싶다고 가정 해 봅시다. 다음은 검색 대소 문자를 구분하지 않는 방법입니다.

대소 문자를 구분하지 않는 in_array () :

foreach($searchKey as $key => $subkey) {

     if (in_array(strtolower($subkey), array_map("strtolower", $subarray)))
     {
        echo "found";
     }

}

대소 문자 구분 :

foreach($searchKey as $key => $subkey) {

if (in_array("$subkey", $subarray))

     {
        echo "found";
     }

}

2

배열은 문자열 만 포함 할 수 있지만 배열은 다른 배열도 포함 할 수 있다고 가정하면 위의 내용이 정확합니다. 또한 in_array () 함수는 $ needle에 대한 배열을 허용 할 수 있으므로 $ needle이 배열이고 $ haystack에 다른 것이 포함되어 있으면 array_map ( 'strtolower', $ haystack)이 작동하지 않으면 strtolower ($ needle)가 작동하지 않습니다 "PHP 경고 : strtolower ()는 매개 변수 1이 문자열이며 배열이 주어질 것으로 예상합니다."

예:

$needle = array('p', 'H');
$haystack = array(array('p', 'H'), 'U');

그래서 대소 문자를 구분하고 대소 문자를 구분하지 않는 in_array () 검사를하기 위해 관련 메소드를 사용하여 도우미 클래스를 만들었습니다. strtolower () 대신 mb_strtolower ()를 사용하고 있으므로 다른 인코딩을 사용할 수 있습니다. 코드는 다음과 같습니다.

class StringHelper {

public static function toLower($string, $encoding = 'UTF-8')
{
    return mb_strtolower($string, $encoding);
}

/**
 * Digs into all levels of an array and converts all string values to lowercase
 */
public static function arrayToLower($array)
{
    foreach ($array as &$value) {
        switch (true) {
            case is_string($value):
                $value = self::toLower($value);
                break;
            case is_array($value):
                $value = self::arrayToLower($value);
                break;
        }
    }
    return $array;
}

/**
 * Works like the built-in PHP in_array() function — Checks if a value exists in an array, but
 * gives the option to choose how the comparison is done - case-sensitive or case-insensitive
 */
public static function inArray($needle, $haystack, $case = 'case-sensitive', $strict = false)
{
    switch ($case) {
        default:
        case 'case-sensitive':
        case 'cs':
            return in_array($needle, $haystack, $strict);
            break;
        case 'case-insensitive':
        case 'ci':
            if (is_array($needle)) {
                return in_array(self::arrayToLower($needle), self::arrayToLower($haystack), $strict);
            } else {
                return in_array(self::toLower($needle), self::arrayToLower($haystack), $strict);
            }
            break;
    }
}
}

1

코드가 아래에있는 배열에서 둔감 한 값을 확인하는 간단한 함수를 작성했습니다.

함수:

function in_array_insensitive($needle, $haystack) {
   $needle = strtolower($needle);
   foreach($haystack as $k => $v) {
      $haystack[$k] = strtolower($v);
   }
   return in_array($needle, $haystack);
}

사용하는 방법:

$array = array('one', 'two', 'three', 'four');
var_dump(in_array_insensitive('fOUr', $array));

1
/**
 * in_array function variant that performs case-insensitive comparison when needle is a string.
 *
 * @param mixed $needle
 * @param array $haystack
 * @param bool $strict
 *
 * @return bool
 */
function in_arrayi($needle, array $haystack, bool $strict = false): bool
{

    if (is_string($needle)) {

        $needle = strtolower($needle);

        foreach ($haystack as $value) {

            if (is_string($value)) {
                if (strtolower($value) === $needle) {
                    return true;
                }
            }

        }

        return false;

    }

    return in_array($needle, $haystack, $strict);

}


/**
 * in_array function variant that performs case-insensitive comparison when needle is a string.
 * Multibyte version.
 *
 * @param mixed $needle
 * @param array $haystack
 * @param bool $strict
 * @param string|null $encoding
 *
 * @return bool
 */
function mb_in_arrayi($needle, array $haystack, bool $strict = false, ?string $encoding = null): bool
{

    if (null === $encoding) {
        $encoding = mb_internal_encoding();
    }

    if (is_string($needle)) {

        $needle = mb_strtolower($needle, $encoding);

        foreach ($haystack as $value) {

            if (is_string($value)) {
                if (mb_strtolower($value, $encoding) === $needle) {
                    return true;
                }
            }

        }

        return false;

    }

    return in_array($needle, $haystack, $strict);

}

드디어. 누군가가 강화하고 가장 효율적인 기술을 제공하기 전에 8 년이 걸렸다 - 을 초return . 바늘 중 하나만 찾아야 할 때, 바늘을 찾은 후에 계속 반복하는 것은 의미가 없습니다. 나는 오타를 고치고 $ strict 개념을 구워서 3v4l.org/WCTi2에 가까운 것을 개선 할 입니다. 이 게시물은 완벽하지는 않지만 그 핵심은 올바른 위치에 있습니다.
mickmackusa

0
$a = [1 => 'funny', 3 => 'meshgaat', 15 => 'obi', 2 => 'OMER'];  

$b = 'omer';

function checkArr($x,$array)
{
    $arr = array_values($array);
    $arrlength = count($arr);
    $z = strtolower($x);

    for ($i = 0; $i < $arrlength; $i++) {
        if ($z == strtolower($arr[$i])) {
            echo "yes";
        }  
    } 
};

checkArr($b, $a);

1
제안하는 솔루션에 대한 설명을 추가하십시오.
il_raffa

-2
  • in_array는 다음 매개 변수를 승인합니다. in_array (search, array, type)
  • 검색 매개 변수가 문자열이고 유형 매개 변수가 TRUE로 설정되면 검색은 대소 문자를 구분합니다.
  • 따라서 검색에서 대소 문자를 무시하려면 다음과 같이 사용하면 충분합니다.

$ a = array ( 'one', 'two', 'three', 'four');

$ b = in_array ( 'ONE', $ a, false);


6
세 번째 매개 변수는 대소 문자가 아닌 변수 유형 의 검사 여부를 제어합니다 . 때 엄격한 타입 비교가 사용됩니다은, 예를 들면 . 시 타입 저글링이 사용됩니다은, 예를 들면 . 설명서는 php.net/in_arrayphp.net/manual/en/types.comparisons.php 를 참조하십시오 . true'1' !== 1false'1' == 1
leepowers
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.