elm / regex / Regex

A library for working with regex. The syntax matches the RegExp library from JavaScript.

Create


type Regex

A regular expression as specified in JavaScript.

fromString : String -> Maybe Regex

Try to create a Regex. Not all strings are valid though, so you get a `Maybe' back. This means you can safely accept input from users.

import Regex

lowerCase : Regex.Regex
lowerCase =
  Maybe.withDefault Regex.never <|
    Regex.fromString "[a-z]+"

Note: There are some shorthand character classes like \w for word characters, \s for whitespace characters, and \d for digits. Make sure they are properly escaped! If you specify them directly in your code, they would look like "\\w\\s\\d".

fromStringWith : Options -> String -> Maybe Regex

Create a Regex with some additional options. For example, you can define fromString like this:

import Regex

fromString : String -> Maybe Regex.Regex
fromString string =
  fromStringWith { caseInsensitive = False, multiline = False } string


type alias Options =
{ caseInsensitive : Basics.Bool
, multiline : Basics.Bool 
}

never : Regex

A regular expression that never matches any string.

Use

contains : Regex -> String -> Basics.Bool

Check to see if a Regex is contained in a string.

import Regex

digit : Regex.Regex
digit =
  Maybe.withDefault Regex.never <|
    Regex.fromString "[0-9]"

-- Regex.contains digit "abc123" == True
-- Regex.contains digit "abcxyz" == False

split : Regex -> String -> List String

Split a string. The following example will split on commas and tolerate whitespace on either side of the comma:

import Regex

comma : Regex.Regex
comma =
  Maybe.withDefault Regex.never <|
    Regex.fromString " *, *"

-- Regex.split comma "tom,99,90,85"     == ["tom","99","90","85"]
-- Regex.split comma "tom, 99, 90, 85"  == ["tom","99","90","85"]
-- Regex.split comma "tom , 99, 90, 85" == ["tom","99","90","85"]

If you want some really fancy splits, a library like elm/parser will probably be easier to use.

find : Regex -> String -> List Match

Find matches in a string:

import Regex

location : Regex.Regex
location =
  Maybe.withDefault Regex.never <|
    Regex.fromString "[oi]n a (\\w+)"

places : List Regex.Match
places =
  Regex.find location "I am on a boat in a lake."

-- map .match      places == [ "on a boat", "in a lake" ]
-- map .submatches places == [ [Just "boat"], [Just "lake"] ]

If you need submatches for some reason, a library like elm/parser will probably lead to better code in the long run.

replace : Regex -> (Match -> String) -> String -> String

Replace matches. The function from Match to String lets you use the details of a specific match when making replacements.

import Regex

userReplace : String -> (Regex.Match -> String) -> String -> String
userReplace userRegex replacer string =
  case Regex.fromString userRegex of
    Nothing ->
      string

    Just regex ->
      Regex.replace regex replacer string

devowel : String -> String
devowel string =
  userReplace "[aeiou]" (\_ -> "") string

-- devowel "The quick brown fox" == "Th qck brwn fx"

reverseWords : String -> String
reverseWords string =
  userReplace "\\w+" (.match >> String.reverse) string

-- reverseWords "deliver mined parts" == "reviled denim strap"


type alias Match =
{ match : String
, index : Basics.Int
, number : Basics.Int
, submatches : List (Maybe String) 
}

The details about a particular match:

Fancier Uses

splitAtMost : Basics.Int -> Regex -> String -> List String

Just like split but it stops after some number of matches.

A library like elm/parser will probably lead to better code in the long run.

findAtMost : Basics.Int -> Regex -> String -> List Match

Just like find but it stops after some number of matches.

A library like elm/parser will probably lead to better code in the long run.

replaceAtMost : Basics.Int -> Regex -> (Match -> String) -> String -> String

Just like replace but it stops after some number of matches.

A library like elm/parser will probably lead to better code in the long run.