문제

일치해야 하는 패턴으로 가득 찬 배열이 있습니다.for() 루프 외에 다른 방법은 없나요?매 분마다 수십 개의 작업을 수행하게 되므로 CPU를 최소한으로 사용하는 방식으로 수행하려고 합니다.

실제 예는 다양한 온라인 비디오 사이트에 대한 링크를 확인하여 비디오가 계속 라이브인지 확인하는 링크 상태 검사기를 구축하는 것입니다.각 도메인에는 여러 개의 "죽은 키워드"가 있습니다. 이러한 키워드가 페이지의 HTML에서 발견되면 파일이 삭제되었음을 의미합니다.이는 배열에 저장됩니다.페이지의 HTML 출력과 배열의 내용을 일치시켜야 합니다.

도움이 되었습니까?

해결책

우선, 문자 그대로 다음 작업만 수행하는 경우 수십 모든 , 그렇다면 이 경우 성능에 대해 크게 걱정하지 않을 것입니다.이러한 일치는 매우 빠르며 패턴 배열을 반복하고 다음과 같이 preg_match를 별도로 호출해도 성능 문제가 발생하지 않을 것이라고 생각합니다.

$matches = false;
foreach ($pattern_array as $pattern)
{
  if (preg_match($pattern, $page))
  {
    $matches = true;
  } 
}

실제로 다음을 사용하여 모든 패턴을 하나로 결합할 수 있습니다. or 일부 사람들이 제안하는 것처럼 연산자를 사용하되 그냥 뺨으로 때리지 마십시오. |.패턴 중 하나라도 있으면 심하게 깨질 것입니다. 포함하다 또는 연산자.

최소한 다음과 같은 괄호를 사용하여 패턴을 그룹화하는 것이 좋습니다.

foreach ($patterns as $pattern)
{
  $grouped_patterns[] = "(" . $pattern . ")";
}
$master_pattern = implode($grouped_patterns, "|");

하지만...이것이 결국 더 빨라지는지 잘 모르겠습니다. 무엇 preg_match이든 PHP이든 루프를 반복해야 합니다.추측해야 한다면 개별 경기가 빠르고 읽기 쉽고 유지 관리하기 쉬울 것이라고 추측합니다.

마지막으로, 성능이 여기서 찾고 있는 것이라면 가장 중요한 일은 정규식이 아닌 일치 항목을 간단한 "문자열 포함" 검사로 끌어내는 것입니다.귀하의 검사 중 일부는 페이지에 "이 사이트가 폐쇄되었습니다"가 있는지 확인하는 것과 같은 간단한 문자열 검사여야 한다고 생각합니다.

그래서 이렇게 합니다:

foreach ($strings_to_match as $string_to_match)
{
  if (strpos($page, $string_to_match) !== false))
  {
    // etc.
    break;
  }
}
foreach ($pattern_array as $pattern)
{
  if (preg_match($pattern, $page))
  {
    // etc.
    break;
  } 
}

그리고 최대한 피하고 preg_match() 가능한 한 아마도 최고의 이득이 될 것입니다. strpos()많은 보다 빠른 preg_match().

다른 팁

// assuming you have something like this
$patterns = array('a','b','\w');

// converts the array into a regex friendly or list
$patterns_flattened = implode('|', $patterns);

if ( preg_match('/'. $patterns_flattened .'/', $string, $matches) )
{
}

// PS: that's off the top of my head, I didn't check it in a code editor

패턴에 많은 공백이 포함되어 있지 않으면 다른 옵션은 배열을 피하고 사용하는 것입니다. /x 수정 자. 이제 정규식 목록은 다음과 같습니다.

$regex = "/
pattern1|   # search for occurences of 'pattern1'
pa..ern2|   # wildcard search for occurences of 'pa..ern2'
pat[ ]tern| # search for 'pat tern', whitespace is escaped
mypat       # Note that the last pattern does NOT have a pipe char
/x";

이랑 /x 수정 자, 공백은 캐릭터 클래스에 있거나 백 슬래시가 선행되는 경우를 제외하고는 완전히 무시됩니다. 위와 같은 의견도 허용됩니다.

이것은 배열을 통한 루핑을 피할 수 있습니다.

다른 문자열에 문자열이 존재하는 것을 검색하는 경우 Strpps를 더 빨리 사용하십시오.

그렇지 않으면 매번 preg_match를 호출하여 패턴 배열을 반복 할 수 있습니다.

많은 패턴이 있다면, 당신이 할 수있는 일은 단일 정규 표현으로 그것들을 연결하고 그것을 일치시키는 것입니다. 루프가 필요하지 않습니다.

a를하는 것은 어떻습니까 str_replace() HTML에서 배열을 사용한 다음 원본 HTML이 원본과 동일했는지 확인하십시오. 이것은 매우 빠릅니다 :

 $sites = array(
      'you_tube' => array('dead', 'moved'),
      ...
 );
 foreach ($sites as $site => $deadArray) {
     // get $html
     if ($html == str_replace($deadArray, '', $html)) { 
         // video is live
     }
 }

목록에서 단일 정규 표현식으로 모든 패턴을 결합 할 수 있습니다. implode () PHP 기능. 그런 다음 사용하여 문자열을 한 번에 테스트하십시오 preg_match () PHP 기능.

$patterns = array(
  'abc',
  '\d+h',
  '[abc]{6,8}\-\s*[xyz]{6,8}',
);

$master_pattern = '/(' . implode($patterns, ')|(') . ')/'

if(preg_match($master_pattern, $string_to_check))
{
  //do something
}

물론 "if ()"조건에서 implode () 인라인을 사용하여 코드가 훨씬 적을 수 있습니다. $master_pattern 변하기 쉬운.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top