[regex] Gadaffi를 검색하는 정규식

가다피 (Gadaffi)라는 단어를 검색하려고합니다. 이것을 검색하는 가장 좋은 정규식은 무엇입니까?

지금까지 최선의 시도는 다음과 같습니다.

\b[KG]h?add?af?fi$\b

그러나 여전히 일부 저널이 누락 된 것 같습니다. 어떤 제안?

업데이트 : 나는 여기에서 꽤 광범위한 목록을 찾았습니다 : http://blogs.abcnews.com/theworldnewser/2009/09/how-many-different-ways-can-you-spell-gaddafi.html

아래의 답변은 30 가지 변형과 모두 일치합니다.

가다피
가다피
가다피
가다피
가다피
가다피
가다피
가타 피
가다피
가다피
가다피
가다피
게다 피
카다피
카다피
카다피
카다피
카자 피
카다피
카다피
카다피
카다피
카다피
카다피
카다피
카다피
카타 피
콰 타피
꾸다 피
카다피



답변

\b[KGQ]h?add?h?af?fi\b

아랍어 전사는 (Wiki에 따르면) “Qaḏḏāfī”이므로 Q를 추가하고 H를 추가 할 수 있습니다 (아래 기사 참조).

Btw, $정규식 끝에 왜 있습니까?


Btw, 주제에 대한 좋은 기사 :

Gaddafi, Kadafi 또는 Qaddafi? 리비아 지도자의 이름이 왜 그렇게 많은 다른 철자로 쓰입니까? .


편집하다

나중에 언급 한 기사의 모든 이름과 일치하려면 모두 일치해야합니다. 그것이 다른 많은 것들과 일치하지 않기를 바랍니다 : D

\b(Kh?|Gh?|Qu?)[aeu](d['dt]?|t|zz|dhd)h?aff?[iy]\b


답변

쉬운 … (Qadaffi|Khadafy|Qadafi|)… 자체 문서화되고 유지 관리가 가능하며 정규 표현식 엔진이 실제로 정규 표현식을 해석하지 않고 컴파일한다고 가정하면 더 난해한 솔루션과 동일한 DFA로 컴파일됩니다.

간단한 정규식을 작성하는 것은 짧은 변수 이름을 사용하여 프로그램 속도를 높이는 것과 같습니다. 컴파일러가 죽어있는 경우에만 도움이됩니다.


답변

잠재적 인 철자 목록에서 주목해야 할 흥미로운 점은 포함 된 목록에 대해 3 개의 Soundex 값만 있다는 것입니다 (이상치 ‘Kazzafi’를 무시하는 경우).

G310, K310, Q310

이제 거기에는 오 탐지 ( ‘Godby’도 G310 임)가 있지만 제한된 메타 폰 적중도 결합하면 제거 할 수 있습니다.

<?
$soundexMatch = array('G310','K310','Q310');
$metaphoneMatch = array('KTF','KTHF','FTF','KHTF','K0F');

$text = "This is a big glob of text about Mr. Gaddafi. Even using compound-Khadafy terms in here, then we might find Mr Qudhafi to be matched fairly well. For example even with apostrophes sprinkled randomly like in Kad'afi, you won't find false positives matched like godfrey, or godby, or even kabbadi";

$wordArray = preg_split('/[\s,.;-]+/',$text);
foreach ($wordArray as $item){
    $rate = in_array(soundex($item),$soundexMatch) + in_array(metaphone($item),$metaphoneMatch);
    if ($rate > 1){
        $matches[] = $item;
    }
}
$pattern = implode("|",$matches);
$text = preg_replace("/($pattern)/","<b>$1</b>",$text);
echo $text;
?>

약간의 조정과 약간의 키릴 음역을 말하면 상당히 강력한 해결책이 있습니다.


답변

CPAN 모듈 Regexp :: Assemble 사용 :

#!/usr/bin/env perl

use Regexp::Assemble;

my $ra = Regexp::Assemble->new;
$ra->add($_) for qw(Gadaffi Gadafi Gadafy Gaddafi Gaddafy
                    Gaddhafi Gadhafi Gathafi Ghadaffi Ghadafi
                    Ghaddafi Ghaddafy Gheddafi Kadaffi Kadafi
                    Kaddafi Kadhafi Kazzafi Khadaffy Khadafy
                    Khaddafi Qadafi Qaddafi Qadhafi Qadhdhafi
                    Qadthafi Qathafi Quathafi Qudhafi Kad'afi);
say $ra->re;

다음과 같은 정규식이 생성됩니다.

(?-xism:(?:G(?:a(?:d(?:d(?:af[iy]|hafi)|af(?:f?i|y)|hafi)|thafi)|h(?:ad(?:daf[iy]|af?fi)|eddafi))|K(?:a(?:d(?:['dh]a|af?)|zza)fi|had(?:af?fy|dafi))|Q(?:a(?:d(?:(?:(?:hd)?|t)h|d)?|th)|u(?:at|d)h)afi))


답변

나는 당신이 여기에서 일을 복잡하게하고 있다고 생각합니다. 올바른 정규 표현식은 다음과 같이 간단합니다.

\u0627\u0644\u0642\u0630\u0627\u0641\u064a

이 단어는 단어 القذافي (즉, Gadaffi)를 형성하는 7 개의 아랍어 유니 코드 코드 포인트의 연결과 일치합니다.


답변

아무도 사용하지 않은 것을 일치시키지 않으려면 (예 : “. +”로 향하는 경향을 피하십시오) 가장 좋은 방법은 모든 대안 (예 : (Qadafi | Kadafi | …) 인 정규식을 만드는 것입니다. ) 그런 다음 DFA로 컴파일 한 다음 DFA를 다시 정규식으로 변환합니다. 예상치 못한 변형을 포함하지 않는 “압축 된”정규식을 제공하는 적당히 합리적인 구현을 가정합니다.


답변

30 가지 가능성에 대한 구체적인 목록을 가지고 있다면, “or”와 함께 모두 연결하십시오. 그런 다음이 될 수 있는지 그것은 단지 당신이 열거 한 정확한 것들과 일치하고, 더 이상있다. RE 엔진은 아마도 그다지 중요하지 않더라도 30 가지 선택으로 더 최적화 할 수있을 것입니다. 수동으로 “영리한”RE로 바꾸면서 장난을 치면 더 나아질 수 없으며 나빠질 수 있습니다.