Группировка в регулярных выражениях haskell

Как я могу извлечь строку, используя регулярные выражения в Haskell?

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

Это не событие, получившее соответствие

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

Это означает, что x заканчивается как "xyz abc", как извлечь только первую группу регулярных выражений, так что x является "xyz"?

Ответы

Ответ 1

Я писал/поддерживал такие пакеты, как regex-base, regex-pcre и regex-tdfa.

В regex-базе модуль Text.Regex.Base.Context документирует большое количество экземпляров RegexContext, которые = ~ использует. Они реализованы поверх RegexLike, который предоставляет основной способ вызова matchText и matchAllText.

[[String]], о котором упоминается KennyTM, является другим экземпляром RegexContext и может быть или не быть тем, который лучше всего подходит для вас. Полный экземпляр

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

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

который можно использовать для получения MatchText для всего:

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

В какой точке x является массивом Int совпадений массива Int групповых совпадений.

Обратите внимание, что "\ w" - это синтаксис Perl, поэтому для его доступа требуется regex-pcre. Если вам нужны расширенные регулярные выражения Unix/Posix, вы должны использовать regex-tdfa, который является кросс-платформенным, и избегать использования regex-posix, который поражает ошибки каждой платформы при реализации библиотеки regex.h.

Обратите внимание, что Perl vs Posix - это не просто синтаксис, например "\ w". Они используют очень разные алгоритмы и часто возвращают разные результаты. Кроме того, сложность времени и пространства очень различна. Для сопоставления с строкой длины 'n' Perl style (regex-pcre) может быть O (exp (n)) во времени, тогда как стиль Posix с использованием regex-posix всегда равен O (n) во времени.

Ответ 2

Передайте результат как [[String]]. Затем вы получите список совпадений, каждый из которых является списком совпадающего текста и захваченных подгрупп.

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