10,000개의 정규식과 하나의 문자열이 있고 그 문자열이 정규식과 일치하는지 알아보고 일치하는 모든 문자열을 가져오고 싶다고 가정해 봅시다. 이를 수행하는 간단한 방법은 모든 정규식에 대해 문자열을 하나씩 쿼리하는 것입니다. 더 빠르고 효율적인 방법이 있을까요?
편집: 나는 그것을 DFA (lex)로 대체하려고 시도했다. 여기서 문제는 하나의 단일 패턴 만 제공한다는 것입니다. 문자열 &"hello&"와 패턴 &"[H|h]ello&"와 &".{0,20}ello&"가 있으면 DFA는 둘 중 하나만 일치하지만 둘 다 맞기를 원합니다.
그 당시 나는 운이 정규 표현식 일반적으로 하위 표시해야 하는 모든 문자열을 내 일부 정보기술 (it) 경기. 나는 이러한 단순 파서를 사용하는 푸십시오 있었습니다 작업공간에서 FSA name. domain. 아호 코라식 알고리즘 및 인덱스화할 서브문자열을. 이 지수는 빠르게 제거 하는 정규 표현식 모두 사용될 때, 주어진 문자열 t # 39 사소 don& 일치시킵니다 확인란만 몇 정규 표현식 확인할 수 있습니다.
I / C 모듈에서는 파이썬 코드를 릴리즈됨 LGPL 하에 있다. 참조 이스마레 구글 코드 호스팅.
[1]: https://stackoverflow.com/questions/192957/efficiently-querying-one-string-against-multiple-regexes # 193000
우리는 이러한 것들을 내가 일했던 한 번 있는 제품. Answer 는 컴파일하십시오 결정적 유한 상태 기계 당신의 모든 정규 표현식 동업이요 붙여넣습니다 (일명 결정적 유한 자동기계 또는 DFA ). 그 후 입을 수 있는 것이라고 할 수 있는 DFA 문자 및 문자 단위로 대한 문자열이어야 불지옥의 " match"; 이벤트 중 하나가 때마다 표현식에서는 일치시킵니다.
A 가 필요하다는 단점이 있으며, 큰 데이터표 대한 여러 가지 유형의 지원하지 않는 일반 표현식에서는 자동기계 (예를 들어, 뒤로를 참조입니다).
우리는 한 손으로 코딩 C++ 템플릿 너트 (nut) 에 의해 사용된 국회의정시스템에도 당시 도왔으매 죄송합니다. don& # 39 점, 내가 없는 모든 포스 솔루션을 향해 있습니다. , Regex 또는 정규식이 " DFA*&quo 함께 구글 신앙이니라 있습니다. # 39 you& 물건을 찾을 수 있는 점, ll 올바른 방향으로 가고 있습니다.
이 방식으로 렉서 작동합니까.
정규 표현식 변환할지 하나의 확고한 오토마타 (NFA) 과 오토마타 (DFA) 에 결정주의 포시빌리 비사양 변신했다.
그 결과 모든 정규 표현식에 대해 일치시키려면 자동기계 노력하겠다고 한꺼번에 성공하지만 그 희망이었네
여기서 그들은 도움을 줄 수 있는 여러 가지 도구를 " 불렀으매 렉서 generator"; 그런데 이 솔루션을 사용할 수 있는 대부분의 언어.
어떤 언어가 don&, t # 39 라고 사용하고 있습니다. C 프로그래머가 꼭 이래야겠어요 제안하세요 목석같은놈. re2c 에 대해 알 수 있다. 물론 일반적인 (f) lex 항상 옵션을 선택합니다.
[마틴 술츠만] (http://sulzmann.blogspot.com/) 는 이 분야에서 아주 조금 작업 완료. 그는 이 [a 해크지db 프로젝트] (http://hackage.haskell.org/cgi-bin/hackage-scripts/package/regexpr-symbolic) [here] 브레이프리 설명했다 (http://sulzmann.blogspot.com/2008/12/equality-containment-and-intersection.html) 를 사용하는 [부분 파생상품] (http://sulzmann.blogspot.com/2008/11/playing-with-regular-expressions.html) 이 맞춤화하도록 위해 만들어진 것으로 보인다.
하스켈 및 카타시안 언어를 사용하는 것은 매우 어려운 경우 이 모든 것이 될 수 있는 언어 변환하기에 비사양 기능 (나는 여전히 많은 것 같은데 다른 언어로 번역 FP 아니하였으매 상당히 어려운).
이 코드는 기반으로 하지 않는 변환 후 따른 것이 아니라 일련의 오토마타 통합하여 기호식 조작의 정규 표현식 것 "이라고 말했다.
또한 코드 매우 실험적인, 마르틴 교수는 그러나 # 39, & # 39 는 더 이상 이익이있는 employment& 무관심한 어떤 도움이 될 수 있으므로, (1) / 공급할 수 없음을 또는 입력입니다.
10,000 리자이스잉 어? [에릭 Wendelin& # 39 의] (https://stackoverflow.com/questions/192957/efficiently-querying-one-string-against-multiple-regexes # 192975) 의 제안으로 계층 좋은 생각인 것 같다. 당신은 돌아보 줄이기 위해 이 같은 일이 비 행을 리자이스잉 트리 구조를?
간단한 예를 있다. 필요로 하는 모든 리자이스잉 지사급 오프하도록 확인하는 등 모든 리자이스잉 필요로 하지 않는 한, regex 번호와 다른 분기로의 one down. 이러한 방식으로 수를 줄일 수 있는 길을 걷고 있는 모든 단일 비교 진단트리를 따라 실제 비교 하는 대신 10,000.
이 때문에 이 장르를 공유 테스트 등을 제공하는 분해하는 필요합니다 리자이스잉 아웃하라는 실패할 경우 각 장르의 규칙을 만들 것이다. 이렇게 하면 이론적으로 수를 대폭 줄일 수 있다면 실제 비교.
이를 통해 런타임에 했을 경우, 주어진 정규 표현식, 구문 분석 및 " file" 수 있습니다. 그 순간 생성할지 salesforce. 미리 정의된 장르 (쉽게 할 수 있는) 또는 비교 장르를 아닌 쉽게 수행할 수 있다).
예, hello" 너회의 " 비교. [H h] 로 " ello"; 및 "}, {0.20 ello". # 39, 정말 이 솔루션을 통해 won& 어떠한 도움도 받지 않는다. 간단한 경우를 약간만이라도 유용할 수 있습니다. 테스트를 했을 경우, 1000년 만 있으면 참 반품하십시오 " ello"; 네, 안녕, 다른 곳에 존재하는 문자열의 테스트 문자열은 " ". 한 가지 테스트를 수행할 수 있을 때와 " 대한 ello"; # 39, 정보기술 (it) 이 1000년 테스트를 won& 성전하라 필요로 하는 일, 이 때문에 t t # 39 won& 저들이요 할 수 있습니다.
어쩌면 20 그룹별로 결합할 수 있습니다.
(?=(regex1)?)(?=(regex2)?)(?=(regex3)?)...(?=(regex20)?)
Regex 는 각 deltamove 제로 (또는 최소한 같은 수의) 얼마인지 확인할 수 있습니다 어떤 캡처하기 그룹화합니다 여바바 캡처됩니다 패턴과 일치시킵니다.
2000년 각 범주에 대한 내가 가진 것을 패턴 열거합니다 일치시키려면 했다. 문자열 길이를 평균 약 100,000 자입니다.
그래서 내가 어렸을 때 사용한 파이썬 https://pypi.python.org/pypi/pyahocorasick/.
import ahocorasick
A = ahocorasick.Automaton()
patterns = [
[['cat','dog'],'mammals'],
[['bass','tuna','trout'],'fish'],
[['toad','crocodile'],'amphibians'],
]
for row in patterns:
vals = row[0]
for val in vals:
A.add_word(val, (row[1], val))
A.make_automaton()
_string = 'tom loves lions tigers cats and bass'
def test():
vals = []
for item in A.iter(_string):
vals.append(item)
return vals
테스트 () '에 대한 추적을 통해 내 2000년 범주입니다 %timeit 호스팅하면서' 카테고리와 '당' 몸 길이는 약 100,000 2-3 _string 'vs' 하고 '내가' ms 'ms' () '' 레이시치 2.09 631 순차인지 315x 빨리 .
(r1)|(r2)|(r3)|...|(r10000)
여기서, 괄호를 그룹화용으로 일치하지 않는. 이 중 적어도 한 기존 정규 표현식에 일치하는 것도 정규식이 일치시킵니다.
부인: 내가 아는 사람 중 유일한 라리브러리 장치당 [루아] 는 [라피크] [2], 3 # 39 wasn&, 정보기술 (it), t easy (가져다줄래요) 잡고 기본 개념.
~ roberto/lpeg/lpeg.html [2]:
1 와 [라헬] 내가 사용하는 것가운데 작업:
action hello {...}
action ello {...}
action ello2 {...}
main := /[Hh]ello/ % hello |
/.+ello/ % ello |
any{0,20} "ello" % ello2 ;
문자열 " hello"; 작업 후 '에서' 죽이려하겠어요 security. 코드의 누구없어요 '여보세요' 블록 '작업' 에 마지막으로 작업이든지 블록이어야 ello2 블록.
괄호는 그들의 정규식 상당히 제한적이고 machine language 를 사용하는 것이 좋습니다 대신 좀 더 일반적인 욕금지 uxfs 국한됨 작동합니까 얻을 수 있습니다.
가장 빠른 길일 (코드는 C #) 이 같은 일이 될 것 같다.
public static List<Regex> FindAllMatches(string s, List<Regex> regexes)
{
List<Regex> matches = new List<Regex>();
foreach (Regex r in regexes)
{
if (r.IsMatch(string))
{
matches.Add(r);
}
}
return matches;
}
아, 당신 것이 가장 빠른 코드의? # 39, 내가 모르는 don& 어졌다면.