why \* escapes even when it is a raw string?
python, regex
Solution
Regular expressions treat the backslash specially. The backslash disables the "magic" behavior of special characters like `*`.
To actually match a backslash, you need to put two in your raw string: `r'\\foo'`
I think what confused you is that backslashes are special in strings and also special for regular expressions. Python has raw strings to simplify your life: in a raw string, backslashes aren't special, leaving you free to think about the special way that the actual regular expression will handle the backslash.
The regular expression compiler will see this sequence of two characters: `\*`
It will see the backslash, and remove the backslash and treat the `*` specially (disable the "magic").
If you are using a raw string, it's easy to create the sequence of two characters: `r'\*'`
But if you are not using a raw string, backslashes are special inside the string, so you need to double the backslash to get one: `'\\*'`
s = '\\*'
assert len(s) == 2
assert s[0] == '\\'
assert s[1] == '*'
If you actually want to match the pattern `\*` then you need a backslash followed by another backslash, to get the match on an actual backslash; then a backslash followed by a `*`, to get the match on an actual `*`.
p = re.compile(r'\\\*')
assert p.search(r'\*')
There are two special rules about backslash in a raw string, and the two go together: a backslash can escape a quote character, and therefore you cannot end a raw string with an odd number of backslashes.
https://docs.python.org/2/faq/design.html#why-can-t-raw-strings-r-strings-end-with-a-backslash
EDIT: @Charles Duffy pointed out that Python's `re` module provides a function that will properly "escape" the special characters, for the times when you want to match them exactly.
import re
s_pat = re.escape(r'*text*')
assert s_pat[0] == '\\'
assert s_pat[1] == '*'
If you wanted to both match literal `*` and use the special behavior of `*`, one way to do it is this:
s_pat = '(' + re.escape(r'*text*') + ')*'
This is a pattern that will match zero or more occurrences of the actual string `*text*`
Problem
I have read that when 'r' prefix is present, a character following a backslash is included in the string without change, and all backslashes are left in the string. But when I create a regex object: `p=re.compile(r'\*(.*?)\*')`, it matches `'*text*'`. I don't understand why it happens. Under my impression it should match `'\*text\*'`.