2011-04-08 2 views
16

하스켈에서 정규 표현식을 사용하여 문자열을 추출하려면 어떻게해야합니까? 이벤트가 일치하지 않습니다하지만 X 내가 그 x가 "XYZ가"그래서 첫 번째 정규 표현식 그룹을 추출 어떻게 "XYZ의 ABC"로 끝나는haskell 정규 표현식 그룹화

let x = "xyz abc" =~ "(.*) .*" :: String 

을하지 않는

let x = "xyz abc" =~ "(\\w+) \\w+" :: String 

?

답변

18

나는 regex-base, regex-pcreregex-tdfa 등의 패키지를 유지/썼다.

정규 표현식에서 Text.Regex.Base.Context 모듈은 = ~이 사용하는 많은 RegexContext 인스턴스를 문서화합니다. 이는 RegexLike 위에 구현되어 matchText 및 matchAllText를 호출하는 기본 방법을 제공합니다.

KennyTM이 언급하는 [[String]]은 RegexContext의 또 다른 인스턴스이며 가장 적합하거나 그렇지 않을 수 있습니다. 점 x는 그룹 일치의 배열이 Int 일치의 배열의 지능이

let x :: Array Int (MatchText String) 
    x = getAllTextMatches $ "xyz abc" =~ "(\\w+) \\w+" 

되는 : 포괄적 인 인스턴스는 모든 것을위한 MatchText을 가져올 수 있습니다

RegexContext a b (AllTextMatches (Array Int) (MatchText b)) 

type MatchText source = Array Int (source, (MatchOffset, MatchLength)) 

입니다.

"\ w"는 Perl 구문이므로 regex-pcre를 사용하여 액세스해야합니다. Unix/Posix 확장 정규 표현식을 원한다면, 크로스 플랫폼 인 regex-tdfa를 사용하고 regex.h 라이브러리를 구현할 때 각 플랫폼의 버그를 치는 regex-posix를 사용하지 않아야합니다.

Perl 대 Posix는 "\ w"와 같은 구문의 문제 만이 아니라는 점에 유의하십시오. 그들은 매우 다른 알고리즘을 사용하고 종종 다른 결과를 반환합니다. 또한 시간과 공간의 복잡성은 매우 다릅니다. 길이 'n'의 문자열과의 매칭을 위해 Perl 스타일 (regex-pcre)은 시간 상 O (exp (n)) 일 수 있으며, regex-posix를 사용하는 Posix 스타일은 항상 O (n)입니다.

13

결과를 [[String]]으로 전송하십시오. 그러면 일치하는 텍스트의 목록과 캡처 된 하위 그룹 인 일치 목록이 표시됩니다.

Prelude Text.Regex.PCRE> "xyz abc more text" =~ "(\\w+) \\w+" :: [[String]] 
[["xyz abc","xyz"],["more text","more"]]