grep - 최대 패턴 수

grep - 최대 패턴 수

크로스워드 검색을 위해 PHP에서 grep을 사용하고 싶습니다. 600,000행의 단일 단어(독일어 단어)가 포함된 단어 목록이 있습니다.

이제 7개의 문자(예: ABCDEFG)를 입력하고 이를 사용하여 5040개의 순열을 모두 만들고(7입니다!) 거의 의미 없는 모든 철자 바꾸기 가능성(예: ABCDEFG, ABCDEGF, ABCDGEF, ...)을 입력하여 단어가 존재하는지 확인하고 싶습니다. 내 목록에.

저는 16GB RAM, PHP 8.0 및 Apache 2.4를 갖춘 Ubuntu 22.04 서버에서 실행하고 있습니다.

이것이 5040개의 철자 바꾸기 단어를 모두 패턴으로 추가하는 가장 좋은 방법입니까? 예를 들어:

shell_exec( 'grep "^ABCDEFG$\|^ABCDEGF$\|..." /path/to/wordlist.txt');

이것이 좋은 습관입니까? 아니면 for next 루프를 사용하여 5040 grep 호출을 하고 항상 하나의 패턴만 갖는 것이 더 낫습니까?

grep이 내가 원하는 만큼 많은 패턴을 취할 수 있다는 것을 읽었지만 내 방법만큼 많은 패턴을 가진 코드를 찾지 못했습니다. 서버 성능에 따라 최대값이 제한될 것으로 생각되지만 아직 테스트해 보지 않았습니다. 서버 속도를 너무 늦추고 싶지 않습니다.

아니면 내 접근 방식이 그다지 좋지 않아서 모범 사례가 완전히 다를까요?

sqlite를 사용하고 sqlite 데이터베이스의 단어 목록을 사용해 보았지만(각 단어에 대해 OR 사용) 시간이 너무 오래 걸리고 불가능합니다.

팁 고마워.

답변1

철자 바꾸기는 문자의 순서에 관심이 없기 때문에 이를 무시하는 것이 합리적일 수도 있습니다. 대신, 테스트 중인 단어의 각 글자 수를 세거나 더 간단하게 단어의 글자를 정렬하세요. 계산되거나 정렬된 문자열이 계산되거나 정렬된 키 문자열 버전과 일치하면 철자 바꾸기 단어가 있는 것입니다.

Perl로 간단한 한 줄 솔루션을 작성할 수 있습니다. 다음 입력 파일을 가져옵니다.

% cat test.txt
manbat
bantam
hello

그러면 정렬 후 "aabmnt"가 포함된 줄이 인쇄됩니다.

% perl -lne 'chomp; print if join("", sort split //, $_) eq "aabmnt"' test.txt
manbat
bantam

join("", sort split //, $_)현재 줄을 가져와 $_문자를 분리하고 정렬한 다음 다시 연결합니다.

또는 더 유용하게는 스크립트에서 키워드를 정렬하여 batman찾을 키워드가 환경을 통해 전달되는 철자 바꾸기 단어를 제공해야 합니다.

% key=batman perl -lne 'chomp; print if join("", sort split //, $_) eq join("", sort split //, $ENV{key})' test.txt
manbat
bantam

관련 정보