2012-11-26 1 views
2

우리는 더 많은 SQL 지향 프로젝트 중 하나에서 RoundhousE 마이그레이션 도구를 사용합니다. 나는 아주 이상한 버그Regex와 무한 루프

특정 SQL 함수 스크립트 정규식의 교체 방법은 결코 돌아 오지 수 (내 고객의 속성이 있기 때문에 슬프게도 나는 스크립트를 제공하지 못할)에 그루터기를 가지고있는 정규식이

과 같은

(?<KEEP1>^(?:[\s\t])*(?:-{2}).*$)|(?<KEEP1>/{1}\*{1}[\S\s]*?\*{1}/{1})|(?<KEEP1>'{1}(?:[^']|\n[^'])*?'{1})|(?<KEEP1>\s)(?<BATCHSPLITTER>GO)(?<KEEP2>\s)|(?<KEEP1>\s)(?<BATCHSPLITTER>GO)(?<KEEP2>$) 

문제는 위임 evaluate_and_replace_batch_split_items에없는

string sql_statement_scrubbed = regex_replace.Replace(sql_to_run, match => evaluate_and_replace_batch_split_items(match, regex_replace)); 

을 반환하지 RounhousE의 코드 라인 그것의 실제 regex.Replace 메서드에서, 나는 정규식 도구에서 정규식을 시도하고 그것도 중단됩니다. RegEx의 전문가 인이 사람이 문제가 무엇인지 확인할 수 있습니까?

편집 : 나는 그것이 작동하지만 -- If no previous, don't report revised 이 SQL 주석에서 ' (아포스트로피)을 제거하면 그뿐만 아니라 그 라인이

자체에서 작동하기 때문에 스크립트에서 다른 텍스트의 조합이어야
+0

어떻게 든 인용 된 문자열의 시작으로 해석하고, 정규식은 "문자열"에 해당하는 끝나는 인용 부호를 찾기 위해 영원히 필요합니다. 내 정규식 (아래 참조)은 이러한 상황이 가져올 수있는 복잡성의 기하 급수적 인 증가에 덜 민감해야하지만 잘못된 텍스트와 여전히 일치 할 수 있습니다. 따라서 질문 : 여러 줄로 사용할 수 있습니까? 이자형. '''로 시작하고'''로 끝나지만 둘 사이에 개행 문자가 들어있는 문자열? –

+0

이 주석을 놓쳤을 가능성이 있습니다. '이 synstax를 좋아하지 않습니다.'및 개행 문자가 있습니다. – Anders

+0

본질적으로 잘못된 문자열 (아포스트로피로 구분 된 문자열에 이스케이프 처리되지 않은 아포스트로피가 없으므로)? 그런 다음 구문 분석 오류로 모든 언어 파서가 실패하는 것처럼 정규 표현식도 실패합니다. –

답변

2

일반적으로 정규 표현식이 영원히 일치 할 때 (또는 일치하지 않는다는 것을 알게 될 때) 대재앙적인 후행 추적 때문입니다. 정규 표현식에는 입력 내용이 무엇인지에 따라 이러한 경우가있을 수 있습니다. 나는 당신의 정규식을 가져다가 불필요한 한정어와 대체물을 제거하면서 조금 정리했다. 이 정규식 :

(?<KEEP1>^\s*--.*$)|(?<KEEP1>/\*[\S\s]*?\*/)|(?<KEEP1>'[^']*')|(?<KEEP1>\s)(?<BATCHSPLITTER>GO)(?<KEEP2>\s|$) 

은 기존 정규식과 정확히 일치하지만 덜 복잡하고 안정적이어야합니다. 시도해주세요.

은 정규식을 변경해야 제대로 문자열 내에서 ('It\'s something else!')를 탈출 아포스트로피를 처리하려면

그것은 당신의 의견에 아포스트로피처럼 보이는
(?<KEEP1>^\s*--.*$)|(?<KEEP1>/\*[\S\s]*?\*/)|(?<KEEP1>'(?:\\.|[^'\\])*')|(?<KEEP1>\s)(?<BATCHSPLITTER>GO)(?<KEEP2>\s|$) 
+0

감사합니다! – Anders

+0

그것은 작동합니다! : D 당신은 Roundhouse에 대한 변경을 저 지르지 않겠습니까? 아니면 그것을해야합니까? – Anders

+0

@ 앤더스 : 잘 듣고 싶습니다. 나는 RoundhousE가 무엇인지 전혀 모릅니다. 그래서 당신이 그것을하는 것이 더 낫다고 생각합니다. :) –