2011-04-08 22 views
16

¿Cómo puedo extraer una cadena con expresiones regulares en Haskell?Agrupación en las expresiones regulares de haskell

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

Eso no evento conseguir un partido

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

Eso hace pero x termina como "abc xyz" ¿Cómo se extrae sólo el primer grupo de expresiones regulares de manera que x es "xyz"?

Respuesta

18

escribí/mantener este tipo de paquetes como regex-base, regex-pcre y regex-tdfa.

En la base de datos regex, el módulo Text.Regex.Base.Context documenta la gran cantidad de instancias de RegexContext que = ~ usa. Estos se implementan en la parte superior de RegexLike que proporciona la forma subyacente para llamar a matchText y matchAllText.

La [[String]] que KennyTM menciona es otra instancia de RegexContext, y puede ser o no la que mejor funcione para usted. Un ejemplo es integral

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

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

que se puede utilizar para obtener una MatchText para todo:

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

Momento en el que x es un Int Matriz de partidos de un Int Matriz de grupo-partidos.

Tenga en cuenta que "\ w" es la sintaxis de Perl, por lo que necesita regex-pcre para acceder a ella. Si desea expresiones regulares extendidas de Unix/Posix, debe usar regex-tdfa que es multiplataforma y evitar el uso de regex-posix que golpea los errores de cada plataforma al implementar la biblioteca regex.h.

Tenga en cuenta que Perl vs Posix no es solo una cuestión de sintaxis como "\ w". Usan algoritmos muy diferentes y a menudo devuelven resultados diferentes. Además, la complejidad del tiempo y el espacio son muy diferentes. Para hacer coincidir contra una cadena de longitud 'n', el estilo Perl (regex-pcre) puede ser O (exp (n)) en el tiempo, mientras que el estilo Posix usando regex-posix es siempre O (n) en el tiempo.

13

Emite el resultado como [[String]]. Luego obtendrá una lista de coincidencias, cada una de las cuales es la lista de texto coincidente y los subgrupos capturados.

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