{"result":{"depiction_url":null,"edges":{},"id":1601,"is_a":["text","documentation","cookbook"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1601"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_cookbook_justenough_re","page_url":{"en":"https:\/\/zotonic.com\/cookbook\/1601\/just-enough-regular-expressions-in-erlang","x-default":"https:\/\/zotonic.com\/cookbook\/1601\/just-enough-regular-expressions-in-erlang"},"preview_url":null,"resource":{"body":"<div>\n            \n  <div class=\"section\">\n\n<p>Learn how to manipulate string data with the <code class=\"docutils literal notranslate\"><span class=\"pre\">re<\/span><\/code> module.<\/p>\n<p><cite>Lloyd R. Prentice August 31, 2011<\/cite><\/p>\n<div class=\"section\">\n<h2>WHY<\/h2>\n<p>The Erlang standard library re provides a powerful suite of functions\nto excute regular expressions to find, replace, and manipulate\nsubstrings within a string or Erlang binary.<\/p>\n<p><cite>Re<\/cite> functions are particularly useful for form validation,\ndecomposing and modifying urls, e-mail addresses, and other common web\nelements represented as strings or binaries.<\/p>\n<p>They are found throughout Zotonic source files.<\/p>\n<p>See: <a class=\"reference external\" href=\"http:\/\/www.erlang.org\/doc\/man\/re.html\">http:\/\/www.erlang.org\/doc\/man\/re.html<\/a><\/p>\n<\/div>\n<div class=\"section\">\n<h2>ASSUMPTIONS<\/h2>\n<p>You have a current version of Erlang installed on your system.<\/p>\n<p>Examples have been tested on Ubuntu 11.04.<\/p>\n<\/div>\n<div class=\"section\">\n<h2>HOW<\/h2>\n<p>Bring up an Erlang terminal:<\/p>\n<div class=\"highlight-bash notranslate\"><div class=\"highlight\"><pre><span><\/span>$ erl\nErlang R14B03 <span class=\"o\">(<\/span>erts-5.8.4<span class=\"o\">)<\/span> <span class=\"o\">[<\/span>source<span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"m\">64<\/span>-bit<span class=\"o\">]<\/span> <span class=\"o\">[<\/span>smp:3:3<span class=\"o\">]<\/span> <span class=\"o\">[<\/span>rq:3<span class=\"o\">]<\/span> <span class=\"o\">[<\/span>async-threads:0<span class=\"o\">]<\/span> <span class=\"o\">[<\/span>kernel-poll:false<span class=\"o\">]<\/span>\n\nEshell V5.8.4  <span class=\"o\">(<\/span>abort with ^G<span class=\"o\">)<\/span>\n<span class=\"m\">1<\/span>&gt;\n<\/pre><\/div>\n<\/div>\n<p>and follow along with the following examples. Modify and re-execute\neach example until you feel comfortable with what’s going on.<\/p>\n<div class=\"section\">\n<h3>What is a regular expression?<\/h3>\n<p>A regular expression is a pattern that is matched against a subject\nstring from left to right.<\/p>\n<p>The power of regular expressions comes from the ability to include\nalternatives and repetitions in the pattern. These are encoded in the\npattern by the use of metacharacters.<\/p>\n<\/div>\n<div class=\"section\">\n<h3>What is a pattern?<\/h3>\n<p>Most characters stand for themselves in a pattern.<\/p>\n<p>The pattern “ick”, for instance, would match the first occurence of\n“ick” in the string “The quick brown fox.”<\/p>\n<p>We’ll use <code class=\"docutils literal notranslate\"><span class=\"pre\">re:run\/2<\/span><\/code> to illustrate. This function checks a string agains a regular expression: <code class=\"docutils literal notranslate\"><span class=\"pre\">run(Subject,RE)<\/span> <span class=\"pre\">-&gt;<\/span> <span class=\"pre\">{match,<\/span> <span class=\"pre\">Captured}<\/span> <span class=\"pre\">|<\/span> <span class=\"pre\">nomatch<\/span><\/code>.<\/p>\n<p>Example:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">6<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span><span class=\"s\">&quot;ick&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">6<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>The atom “match” is self-explanatory. The tuple {6,3} in the list provides the start position and length of the pattern in the subject string.<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">7<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The brown fox.&quot;<\/span><span class=\"p\">,<\/span><span class=\"s\">&quot;ick&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"n\">nomatch<\/span>\n<\/pre><\/div>\n<\/div>\n<p>re:run\/2 will also work with a binary:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">8<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"o\">&lt;&lt;<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"o\">&gt;&gt;<\/span><span class=\"p\">,<\/span><span class=\"s\">&quot;ick&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">6<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>If we wish to find all instances of “ick” in a string, we need to use\nre:run\/3, <code class=\"docutils literal notranslate\"><span class=\"pre\">run(Subject,RE,Options)<\/span> <span class=\"pre\">-&gt;<\/span> <span class=\"pre\">{match,<\/span> <span class=\"pre\">Captured}<\/span> <span class=\"pre\">|<\/span> <span class=\"pre\">match<\/span> <span class=\"pre\">|<\/span> <span class=\"pre\">nomatch<\/span><\/code>.<\/p>\n<p>Example:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">9<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The sick quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;ick&quot;<\/span><span class=\"p\">,<\/span> <span class=\"p\">[<\/span><span class=\"n\">global<\/span><span class=\"p\">]).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[[{<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}],[{<\/span><span class=\"mi\">11<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}]]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>For documentation of re:run\/3 options, see http:\/\/www.erlang.org\/doc\/man\/re.html<\/p>\n<\/div>\n<div class=\"section\">\n<h3>How can I replace a substring in a string?<\/h3>\n<p>Use <code class=\"docutils literal notranslate\"><span class=\"pre\">re:replace\/3<\/span><\/code>: <code class=\"docutils literal notranslate\"><span class=\"pre\">replace(Subject,<\/span> <span class=\"pre\">RE,<\/span> <span class=\"pre\">Replacement)<\/span> <span class=\"pre\">-&gt;<\/span> <span class=\"pre\">iodata()<\/span> <span class=\"pre\">|<\/span> <span class=\"pre\">unicode:charlist()<\/span><\/code>.<\/p>\n<p>Example:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">10<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;brown&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;red&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">[<\/span><span class=\"o\">&lt;&lt;<\/span><span class=\"s\">&quot;The quick &quot;<\/span><span class=\"o\">&gt;&gt;<\/span><span class=\"p\">,<\/span><span class=\"o\">&lt;&lt;<\/span><span class=\"s\">&quot;red&quot;<\/span><span class=\"o\">&gt;&gt;<\/span><span class=\"p\">|<\/span><span class=\"o\">&lt;&lt;<\/span><span class=\"s\">&quot; fox.&quot;<\/span><span class=\"o\">&gt;&gt;<\/span><span class=\"p\">]<\/span>\n<\/pre><\/div>\n<\/div>\n<p>Hmmm… re:replace\/3 returns an odd-looking binary, which is called an\n<cite>iolist<\/cite>: an efficient data structure, used like this to prevent\ncopying of data in memory.<\/p>\n<p>But, let’s use re:replace\/4 to provide an option: <code class=\"docutils literal notranslate\"><span class=\"pre\">replace(Subject,<\/span> <span class=\"pre\">RE,<\/span> <span class=\"pre\">Replacement,<\/span> <span class=\"pre\">Options)<\/span> <span class=\"pre\">-&gt;<\/span> <span class=\"pre\">iodata()<\/span> <span class=\"pre\">|<\/span> <span class=\"pre\">unicode:charlist()<\/span><\/code>:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">11<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;brown&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;red&quot;<\/span><span class=\"p\">,<\/span> <span class=\"p\">[{<\/span><span class=\"n\">return<\/span><span class=\"p\">,<\/span> <span class=\"n\">list<\/span><span class=\"p\">}]).<\/span>\n<span class=\"s\">&quot;The quick red fox.&quot;<\/span>\n<\/pre><\/div>\n<\/div>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">{return,<\/span> <span class=\"pre\">list}<\/span><\/code> does the trick of returning a “regular”\nstring. Erlang documentation is generally thorough, but often not that\neasy to follow. That’s why I created this Cookbook item. I wanted to\nlearn this stuff myself.<\/p>\n<p>Regular expressions can deliver much much more, however, with shrewd\nuse of metacharacters.<\/p>\n<\/div>\n<div class=\"section\">\n<h3>What is a metacharacter?<\/h3>\n<p>Metacharacters are interpreted in special ways. For instance, the\nmetacharacter . matches the first instance of any character in a\nstring except newline.<\/p>\n<p>Example:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">13<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;.&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>You’d usually use . in a more elaborate pattern:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">14<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;qu.&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}]}<\/span>\n\n<span class=\"mi\">15<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quack brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;qu.&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>The metachacter ^ asserts start of string.<\/p>\n<p>Examples:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">16<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quack brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;^The&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}]}<\/span>\n\n<span class=\"mi\">17<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quack brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;^qua&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"n\">nomatch<\/span>\n<\/pre><\/div>\n<\/div>\n<p>Similarly, the metacharacter $ asserts the end of a line:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">18<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox is sick.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;ick.$&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">24<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>The metacharacter * matches zero or more characters.<\/p>\n<p>Examples:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">19<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;i*&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span><span class=\"mi\">0<\/span><span class=\"p\">}]}<\/span>\n\n<span class=\"mi\">20<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;T*&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}]}<\/span>\n\n<span class=\"mi\">21<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;TTTTThe quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;T*&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span><span class=\"mi\">5<\/span><span class=\"p\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>The metacharacter + matches one or more characters:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">22<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;TTTTThe quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;z+&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"n\">nomatch<\/span>\n\n<span class=\"mi\">23<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;TTTTThe quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;T+&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span><span class=\"mi\">5<\/span><span class=\"p\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>The metacharacter | alternate patterns. Think of it as “or”:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">24<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;fox|pig&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">16<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}]}<\/span>\n\n<span class=\"mi\">25<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown pig.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;fox|pig&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">16<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>You can also match generic character types. s, for instance matches\nany whitespace character.<\/p>\n<p>Examples:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">26<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox&quot;<\/span><span class=\"p\">,<\/span><span class=\"s\">&quot;<\/span><span class=\"se\">\\s<\/span><span class=\"s\">&quot;<\/span><span class=\"p\">,[<\/span><span class=\"n\">global<\/span><span class=\"p\">]).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[[{<\/span><span class=\"mi\">3<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}],[{<\/span><span class=\"mi\">9<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}],[{<\/span><span class=\"mi\">15<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}]]}<\/span>\n<\/pre><\/div>\n<\/div>\n<\/div>\n<div class=\"section\">\n<h3>How can I match non-printing characters?<\/h3>\n<p>See: Non-printing characters <a class=\"reference external\" href=\"http:\/\/www.erlang.org\/doc\/man\/re.html\">http:\/\/www.erlang.org\/doc\/man\/re.html<\/a><\/p>\n<p>Note that the metacharacters [ and ] have special meaning, they\nenclose “character classes.”  A character class is the set of\ncharacters in a character class match, if any found, one character in\nthe subject string.<\/p>\n<p>Examples:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">24<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;[qui]&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}]}<\/span>\n\n<span class=\"mi\">25<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;[ui]&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[{<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}]}<\/span>\n\n<span class=\"mi\">26<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;The quick brown fox.&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s\">&quot;[qui]&quot;<\/span><span class=\"p\">,<\/span> <span class=\"p\">[<\/span><span class=\"n\">global<\/span><span class=\"p\">]).<\/span>\n<span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,[[{<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}],[{<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}],[{<\/span><span class=\"mi\">6<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">}]]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>You can combine characters, meta-characters, and other regular\nexpression elements into extended patterns that can search, match, and\nreplace nearly any substrings you can imagine.<\/p>\n<p>Example:<\/p>\n<div class=\"highlight-bash notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"m\">27<\/span>&gt; re:run<span class=\"o\">(<\/span><span class=\"s2\">&quot;E-mail: xyz@pdq.com&quot;<\/span>, <span class=\"s2\">&quot;[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-z]{2,3}&quot;<\/span><span class=\"o\">)<\/span>.\n<span class=\"o\">{<\/span>match,<span class=\"o\">[{<\/span><span class=\"m\">8<\/span>,11<span class=\"o\">}]}<\/span>\n<\/pre><\/div>\n<\/div>\n<p>Note: DO NOT use this pattern in production. It needs more refinement and much more testing.<\/p>\n<p>What other goodies does <code class=\"docutils literal notranslate\"><span class=\"pre\">re<\/span><\/code> offer?<\/p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">split(Subject,<\/span> <span class=\"pre\">RE)<\/span> <span class=\"pre\">-&gt;<\/span> <span class=\"pre\">SplitList<\/span><\/code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">split(Subject,<\/span> <span class=\"pre\">RE,<\/span> <span class=\"pre\">Options)<\/span> <span class=\"pre\">-&gt;<\/span> <span class=\"pre\">SplitList<\/span><\/code>.<\/p>\n<p>Examples:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"mi\">28<\/span><span class=\"o\">&gt;<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;this\/is\/my\/path&quot;<\/span><span class=\"p\">,<\/span><span class=\"s\">&quot;\/&quot;<\/span><span class=\"p\">).<\/span>\n<span class=\"p\">[<\/span><span class=\"o\">&lt;&lt;<\/span><span class=\"s\">&quot;this&quot;<\/span><span class=\"o\">&gt;&gt;<\/span><span class=\"p\">,<\/span><span class=\"o\">&lt;&lt;<\/span><span class=\"s\">&quot;is&quot;<\/span><span class=\"o\">&gt;&gt;<\/span><span class=\"p\">,<\/span><span class=\"o\">&lt;&lt;<\/span><span class=\"s\">&quot;my&quot;<\/span><span class=\"o\">&gt;&gt;<\/span><span class=\"p\">,<\/span><span class=\"o\">&lt;&lt;<\/span><span class=\"s\">&quot;path&quot;<\/span><span class=\"o\">&gt;&gt;<\/span><span class=\"p\">]<\/span>\n<\/pre><\/div>\n<\/div>\n<p>If you wish to use a pattern multiple times and boost perfomance, you\ncan compile it with <code class=\"docutils literal notranslate\"><span class=\"pre\">re:compile\/1<\/span><\/code>.<\/p>\n<p>Example:<\/p>\n<div class=\"highlight-none notranslate\"><div class=\"highlight\"><pre><span><\/span>29&gt;  {_, P} = re:compile(&quot;[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-z]{2,3}&quot;).\n{ok,{re_pattern,0,0,\n              &lt;&lt;69,82,67,80,164,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,64,\n                ...&gt;&gt;}}\n30&gt; re:run(&quot;E-mail: xyz@pdq.com&quot;, P).\n{match,[{8,11}]}\n<\/pre><\/div>\n<\/div>\n<p>How are regular expressions used in Zotonic source?<\/p>\n<p>For one of many examples, look at <code class=\"docutils literal notranslate\"><span class=\"pre\">zotonic\/src\/markdown\/get_url\/1<\/span><\/code>:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"nf\">get_url<\/span><span class=\"p\">(<\/span><span class=\"nv\">String<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span>\n  <span class=\"nv\">HTTP_regex<\/span> <span class=\"o\">=<\/span> <span class=\"s\">&quot;^(H|h)(T|t)(T|t)(P|p)(S|s)*:\/\/&quot;<\/span><span class=\"p\">,<\/span>\n  <span class=\"k\">case<\/span> <span class=\"nn\">re<\/span><span class=\"p\">:<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"nv\">String<\/span><span class=\"p\">,<\/span> <span class=\"nv\">HTTP_regex<\/span><span class=\"p\">)<\/span> <span class=\"k\">of<\/span>\n      <span class=\"n\">nomatch<\/span>    <span class=\"o\">-&gt;<\/span> <span class=\"n\">not_url<\/span><span class=\"p\">;<\/span>\n      <span class=\"p\">{<\/span><span class=\"n\">match<\/span><span class=\"p\">,<\/span> <span class=\"p\">_}<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">get_url1<\/span><span class=\"p\">(<\/span><span class=\"nv\">String<\/span><span class=\"p\">,<\/span> <span class=\"p\">[])<\/span>\n  <span class=\"k\">end<\/span><span class=\"p\">.<\/span>\n<\/pre><\/div>\n<\/div>\n<p>Where can I go from here?<\/p>\n<p>Study and experiment with all the metacharacters and other regular\nexpression constructs in:<\/p>\n<p><a class=\"reference external\" href=\"http:\/\/www.erlang.org\/doc\/man\/re.html\">http:\/\/www.erlang.org\/doc\/man\/re.html<\/a><\/p>\n<p>Do further research on the web. Everytime you see an interesting\nregular expression, test it in re:run\/2. You may well have to edit to\nget it to run on re:run\/2. But if you understand the basics, it won’t\nbe difficult.<\/p>\n<\/div>\n<\/div>\n<div class=\"section\">\n<h2>TROUBLESHOOTING<\/h2>\n<p>CAUTION: Complex regular expression patterns are hard to read and\nerror prone. Break them down into short segments and test each\nsegment. Then build them back up.<\/p>\n<p>The hard part is confirming that your pattern will match all possible\ninstances of the string segments you’re interested in.<\/p>\n<\/div>\n<div class=\"section\">\n<h2>RESOURCES<\/h2>\n<p><a class=\"reference external\" href=\"http:\/\/www.erlang.org\/doc\/man\/re.html\">http:\/\/www.erlang.org\/doc\/man\/re.html<\/a>\n<a class=\"reference external\" href=\"http:\/\/langref.org\/erlang\/pattern-matching\">http:\/\/langref.org\/erlang\/pattern-matching<\/a>\n<a class=\"reference external\" href=\"http:\/\/www.regular-expressions.info\/examples.html\">http:\/\/www.regular-expressions.info\/examples.html<\/a><\/p>\n<\/div>\n<\/div>\n\n\n           <\/div>","category_id":{"id":318,"is_a":["meta","category"],"name":"cookbook","title":{"_type":"trans","tr":{"en":"Cookbook"}},"uri":"https:\/\/test.zotonic.com\/id\/318"},"content_group_id":{"id":339,"is_a":["meta","content_group"],"name":"default_content_group","title":{"_type":"trans","tr":{"en":"Default Content Group"}},"uri":"https:\/\/zotonic.com\/id\/default_content_group"},"created":"2020-05-30T05:47:27Z","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"github_url":"https:\/\/github.com\/zotonic\/zotonic\/tree\/master\/doc\/cookbook\/justenough-re.rst","is_authoritative":true,"is_dependent":false,"is_featured":false,"is_protected":false,"is_published":true,"is_unfindable":false,"language":["en"],"modified":"2022-02-15T10:01:41Z","modifier_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"name":"doc_cookbook_justenough_re","pivot_geocode":null,"pivot_location_lat":null,"pivot_location_lng":null,"privacy":0,"publication_end":"9999-06-01T00:00:00Z","publication_start":"2022-02-15T10:01:41Z","slug":"just-enough-regular-expressions-in-erlang","title":"Just Enough Regular Expressions (in Erlang)","title_slug":"just-enough-regular-expressions-in-erlang","tz":"UTC","uri":null,"version":18,"visible_for":0},"uri":"https:\/\/zotonic.com\/id\/1601","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1601"}},"status":"ok"}