fireproofsocks

fireproofsocks

When is \s not a \s? Can someone explain Regex patterns?

A \s inside a string represents a space, i.e. " ". In other words:

iex> " " === "\s"
true
iex> "this is a string" === "this\sis\sa\sstring"
true

However, inside a regular expression, the \s takes on a different meaning: it is shorthand for “whitespace character”, so it can match on tabs, newlines, and more. Here it can replace all of them in one swoop:

iex> str = "\tsome\nthing   with\f\nspaces\s\s"
"\tsome\nthing   with\f\nspaces  "
iex> Regex.replace(~r/\s+/, str, "-")
"-some-thing-with-spaces-"

Whereas if you just want to replace literal spaces, you have to explicitly use a space character and NOT \s:

iex> Regex.replace(~r/ +/, str, "-")
"\tsome\nthing-with\f\nspaces-"

By contrast, you can replace specific characters like tabs by referencing them literally:

iex> Regex.replace(~r/\t+/, str, "-")
"-some\nthing   with\f\nspaces  "

Can someone explain why this is the case? I just had this realization that \s is not a \s and I wanted to put the thought out to the community in a coherent post.

Related, I finally understand how the u unicode flag can affect the output. E.g. referencing a chart of whitespace characters, we can come up with a string that uses unicode whitespace characters:

iex> str = "Unicode\u00A0spaces\u2006"
"Unicode spaces "
iex> Regex.replace(~r/\s+/, str, "-")
"Unicode spaces "  # <-- spaces not matched!
iex> Regex.replace(~r/\s+/u, str, "-")
"Unicode-spaces-"  #< -- the u flag causes the spaces to be matched!

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

How the \s is interpreted depends on the surrounding syntax, which all sigils have an opportunity to change. For example:

iex(3)> IO.puts "\s"
 
:ok
iex(4)> IO.puts ~S(\s)
\s
:ok
iex(5)> 

It isn’t so much about regular expressions as it is about sigils being allowed to interpret their inner contents.

Nicd

Nicd

You are mixing two different syntaxes. Strings and regular expressions are different things and have different escapes.

Strings/sigils in Elixir have these escapes: https://elixir-lang.org/getting-started/sigils.html#interpolation-and-escaping-in-string-sigils

Elixir’s regular expression library on the other hand is based on PCRE and it has the PCRE escapes, that are described here: http://erlang.org/doc/man/re.html#backslash

Both systems are different and any commonalities in their escapes are coincidental and a result of people gravitating towards the escapes that are already in common use when designing systems. So \s in a string is different from \s in a regex.

Note also that in strings/sigils, escapes are used to represent single, specific characters. In a regex escapes can be used to match certain ranges of characters (1…n). So they can’t be mapped to each other because they are for different things.

Where Next?

Popular in Questions Top

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

Other popular topics Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement