![]() |
|
[Tut] How to Match an Exact Word in Python Regex? (Answer: Don’t) - Printable Version +- Sick Gaming (https://sickgaming.net) +-- Forum: Programming (https://sickgaming.net/forum-76.html) +--- Forum: Python (https://sickgaming.net/forum-83.html) +--- Thread: [Tut] How to Match an Exact Word in Python Regex? (Answer: Don’t) (/thread-93926.html) |
[Tut] How to Match an Exact Word in Python Regex? (Answer: Don’t) - xSicKxBot - 03-08-2020 How to Match an Exact Word in Python Regex? (Answer: Don’t) This morning, I read over an actual Quora thread with this precise question. While there’s no dumb question, the question reveals that there may be some gap in understanding the basics in Python and Python’s regular expression library. So if you’re an impatient person, here’s the short answer: How to match an exact word/string using a regular expression in Python? You don’t! Well, you can do it by using the straightforward regex Code: 'hello'Code: 'hello world'Code: 'hello'Code: 'hello world'So far so good. But let’s dive into some more specific questions—because you may not exactly have looked for this simplistic answer. In fact, there are multiple ways of understanding your question and I have tried to find all interpretations and answered them one by one: (You can also watch my tutorial video as you go over the article) How to Check Membership of a Word in a String (Python Built-In)? This is the simple answer, you’ve already learned. Instead of matching an exact string, it’s often enough to use Python’s Code: inThus, you should rely on this method if possible: Code: >>> 'hello' in 'hello world'
TrueThe first example shows the most straightforward way of doing it: simply ask Python whether a string is “in” another string. This is called the membership operator and it’s very efficient. You can also check whether a string does not occur in another string. Here’s how: Code: >>> 'hi' not in 'hello world'
TrueThe negative membership operator Code: s1 not in s2Code: TrueCode: s1Code: s2But there’s a problem with the membership operator. The return value is only a Boolean value. However, the advantage of Python’s regular expression library Code: reSo let’s explore the problem of exact string matching using the regex library next: How to Match an Exact String (Regex)? Here’s how you can match an exact substring in a given string: Code: >>> import re
>>> re.search('hello', 'hello world')
<re.Match object; span=(0, 5), match='hello'>After importing Python’s library for regular expression processing Code: reCode: re.search(pattern, string)Code: patternCode: stringThis returns a match object that wraps a lot of useful information such as the start and stop matching positions and the matching substring. As you’re looking for exact string matches, the matching substring will always be the same as your searched word. But wait, there’s another problem: you wanted an exact match, right? But this also means that you’re getting prefix matches of your searched word: Code: >>> re.search('good', 'goodbye')
<re.Match object; span=(0, 4), match='good'>When searching for the exact word Code: 'good'Code: 'goodbye'If not, read on: How to Match a Word in a String (Word Boundary \b)? So how can we fix the problem that an exact match of a word will also retrieve matching substrings that occur anywhere in the string? Here’s an example: Code: >>> 'no' in 'nobody knows'
TrueAnd another example: Code: >>> re.search('see', 'dfjkyldsssseels')
<re.Match object; span=(10, 13), match='see'>What if you want to match only whole words—not exact substrings? The answer is simple: use the word boundary metacharacter Code: '\b'Here’s how you use the word boundary character to ensure that only whole words match: Code: >>> import re
>>> re.search(r'\bno\b', 'nobody knows')
>>> >>> re.search(r'\bno\b', 'nobody knows nothing - no?')
<re.Match object; span=(23, 25), match='no'>In both examples, you use the same regex Code: '\bno\b'Code: 'no'Code: '\b'Code: 'no'As a result, the regex doesn’t match in the string Code: 'nobody knows'Code: 'nobody knows nothing - no?'Note that we use raw string Code: r'...'Code: '\b'Code: '\'Code: 'b'Code: '\b'But what if you don’t care whether the word is upper or lowercase or capitalized? In other words: How to Match a Word in a String (Case Insensitive)? You can search for an exact word in a string—but ignore capitalization. This way, it’ll be irrelevant whether the word’s characters are lowercase or uppercase. Here’s how: Code: >>> import re
>>> re.search('no', 'NONONON', flags=re.IGNORECASE)
<re.Match object; span=(0, 2), match='NO'>
>>> re.search('no', 'NONONON', flags=re.I)
<re.Match object; span=(0, 2), match='NO'>
>>> re.search('(?i)no', 'NONONON')
<re.Match object; span=(0, 2), match='NO'>All three ways are equivalent: they all ignore the capitalization of the word’s letters. If you need to learn more about the Code: flagsCode: (?i)How to Find All Occurrences of a Word in a String? Okay, you’re never satisfied, are you? So let’s explore how you can find all occurrences of a word in a string. In the previous examples, you used the Code: re.search(pattern, string)Code: patternCode: stringNext, you’ll learn how to find all occurrences (not only the first match) by using the Code: re.findall(pattern, string)Code: >>> import re
>>> re.findall('no', 'nononono')
['no', 'no', 'no', 'no']Your code retrieves all matching substrings. If you need to find all match objects rather than matching substrings, you can use the re.finditer(pattern, string) method: Code: >>> for match in re.finditer('no', 'nonononono'): print(match) <re.Match object; span=(0, 2), match='no'>
<re.Match object; span=(2, 4), match='no'>
<re.Match object; span=(4, 6), match='no'>
<re.Match object; span=(6, 8), match='no'>
<re.Match object; span=(8, 10), match='no'>
>>>The Code: re.finditer(pattern, string)How to Find All Lines Containing an Exact Word? Say you want to find all lines that contain the word ’42’ from a multi-line string in Python. How’d you do it? The answer makes use of a fine Python regex specialty: the dot regex matches all characters, except the newline character. Thus, the regex Code: .*Here’s how you can use this fact to get all lines that contain a certain word: Code: >>> import re
>>> s = '''the answer is 42
the answer: 42
42 is the answer
43 is not'''
>>> re.findall('.*42.*', s)
['the answer is 42', 'the answer: 42', '42 is the answer']Three out of four lines contain the word Code: '42'Code: findall()How to Find All Lines Not Containing an Exact Word? In the previous section, you’ve learned how to find all lines that contain an exact word. In this section, you’ll learn how to do the opposite: find all lines that NOT contain an exact word. This is a bit more complicated. I’ll show you the code first and explain it afterwards: Code: import re
s = '''the answer is 42
the answer: 42
42 is the answer
43 is not
the answer
42''' for match in re.finditer('^((?!42).)*$', s, flags=re.M): print(match) '''
<re.Match object; span=(49, 58), match='43 is not'>
<re.Match object; span=(59, 69), match='the answer'> '''You can see that the code successfully matches only the lines that do not contain the string Code: '42'How can you do it? The general idea is to match a line that doesn’t contain the string ‘ Code: 42'Code: re.finditer(pattern, string)The regex pattern Code: '^((?!42).)*$'Code: '^'Code: '$'In between, you match an arbitrary number of characters: the asterisk quantifier does that for you. If you need help understanding the asterisk quantifier, check out this blog tutorial. Which characters do you match? Only those where you don’t have the negative word Code: '42'As the lookahead itself doesn’t consume a character, we need to consume it manually by adding the dot metacharacter Code: .Code: '\n'Finally, you need to define the Code: re.MULTILINECode: re.MCode: ^Code: $Together, this regular expression matches all lines that do not contain the specific word Code: '42'Where to Go From Here? Summary: You’ve learned multiple ways of matching an exact word in a string. You can use the simple Python membership operator. You can use a default regex with no special metacharacters. You can use the word boundary metacharacter Code: '\b'Code: re.IGNORECASECode: re.findall()Code: re.finditer()Pheww. This was some theory-heavy stuff. Do you feel like you need some more practical stuff next? Then check out my practice-heavy Python freelancer course that helps you prepare for the worst and create a second income stream by creating your thriving coding side-business online. https://blog.finxter.com/become-python-freelancer-course/ |