{"id":109764,"date":"2020-02-29T10:22:20","date_gmt":"2020-02-29T10:22:20","guid":{"rendered":"https:\/\/blog.finxter.com\/?p=6476"},"modified":"2020-02-29T10:22:20","modified_gmt":"2020-02-29T10:22:20","slug":"python-regex-multiple-repeat-error","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2020\/02\/29\/python-regex-multiple-repeat-error\/","title":{"rendered":"Python Regex Multiple Repeat Error"},"content":{"rendered":"<p>Just like me an hour ago, you&#8217;re probably sitting in front of your regular expression code, puzzled by a strange error message:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">re.error: multiple repeat at position x<\/pre>\n<p>How does it arise? Where does it come from? And, most importantly, how can you get rid of it?<\/p>\n<p>This article gives you answers to all of those questions. Alternatively, you can also watch my short explainer video that shows you real quick how to resolve this error:<\/p>\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-rich is-provider-embed-handler wp-embed-aspect-16-9 wp-has-aspect-ratio\">\n<div class=\"wp-block-embed__wrapper\">\n<div class=\"ast-oembed-container\"><iframe loading=\"lazy\" title=\"Python Regex Multiple Repeat Error\" width=\"1100\" height=\"619\" src=\"https:\/\/www.youtube.com\/embed\/BtogzCIT4zA?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/div>\n<\/p><\/div>\n<\/figure>\n<h2>How Does the Multiple Repeat Error Arise in Python Re?<\/h2>\n<p><strong>Python&#8217;s <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/blog.finxter.com\/python-regex\/\" target=\"_blank\">regex library re<\/a> throws the multiple repeat error when you try to stack two regex quantifiers on top of each other. For example, the regex <code>'a++'<\/code> will cause the multiple repeat error. You can get rid of this error by avoiding to stack quantifiers on top of each other. <\/strong><\/p>\n<p>Here&#8217;s an example:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">>>> import re\n>>> re.findall('a++', 'aaaa')\nTraceback (most recent call last): File \"&lt;pyshell#29>\", line 1, in &lt;module> re.findall('a++', 'aaaa') File \"C:\\Users\\xcent\\AppData\\Local\\Programs\\Python\\Python37\\lib\\re.py\", line 223, in findall ...\nre.error: multiple repeat at position 2<\/pre>\n<p>I have shortened the error message to focus on the relevant parts. In the code, you first import the regex library re. You then use the <code>re.findall(pattern, string)<\/code> function (<a rel=\"noreferrer noopener\" aria-label=\"see this blog tutorial (opens in a new tab)\" href=\"https:\/\/blog.finxter.com\/python-re-findall\/\" target=\"_blank\">see this blog tutorial<\/a>) to find the pattern <code>'a++'<\/code> in the string <code>'aaaa'<\/code>.<\/p>\n<p>However, this doesn&#8217;t make a lot of sense: what&#8217;s the meaning of the pattern <code>a++<\/code> anyway?<\/p>\n<h2>[Tips] What&#8217;s the Source of the Multiple Repeat Error and How to Avoid It?<\/h2>\n<p>The error happens if you use the Python <a rel=\"noreferrer noopener\" aria-label=\"regex (opens in a new tab)\" href=\"https:\/\/blog.finxter.com\/python-regex\/\" target=\"_blank\">regex<\/a> package <code>re<\/code>. There are many different reasons for it but all of them have the same source: you stack quantifiers on top of each other. <\/p>\n<p>If you don&#8217;t know what a quantifier is, scroll down and read the following subsection where I show you exactly what it is.<\/p>\n<p>Here&#8217;s a list of reasons for the error message. Maybe your reason is among them?<\/p>\n<ul>\n<li>You use the regex pattern <code>'X++'<\/code> for any regex expression <code>X<\/code>. To avoid this error, get rid of one quantifier.<\/li>\n<li>You use the regex pattern <code>'X+*'<\/code> for any regex expression <code>X<\/code>. To avoid this error, get rid of one quantifier.<\/li>\n<li>You use the regex pattern <code>'X**'<\/code> for any regex expression <code>X<\/code>. To avoid this error, get rid of one quantifier.<\/li>\n<li>You use the regex pattern <code>'X{m,n}*'<\/code> for any regex expression <code>X<\/code> and number of repetitions <code>m<\/code> and <code>n<\/code>. To avoid this error, get rid of one quantifier.<\/li>\n<li>You try to match a number of characters <code>'+'<\/code> and use a second quantifier on top of it such as <code>'+?'<\/code>. In this case, you should escape the first quantifier symbol <code>'\\+'<\/code>. <\/li>\n<li>You try to match a number of characters <code>'*'<\/code> and use a second quantifier on top of it such as <code>'*+'<\/code>. Avoid this error by escaping the first quantifier symbol <code>'\\*'<\/code>. <\/li>\n<\/ul>\n<p>Oftentimes, the error appears if you don&#8217;t properly escape the special quantifier metacharacters in your regex pattern. <\/p>\n<p>Here&#8217;s a <a rel=\"noreferrer noopener\" aria-label=\"StackOverflow (opens in a new tab)\" href=\"https:\/\/stackoverflow.com\/questions\/19942314\/python-multiple-repeat-error\" target=\"_blank\">StackOverflow<\/a> post that shows some code where this happened:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">...\nterm = 'lg incite\" OR author:\"http++www.dealitem.com\" OR \"for sale'\np = re.compile(term, re.IGNORECASE) ...<\/pre>\n<p>I edited the given code snippet to show the important part. The code fails because of a <code>multiple repeat error<\/code>. Can you see why?<\/p>\n<p>The reason is that the regex <code>'lg incite\" OR author:\"http++www.dealitem.com\" OR \"for sale'<\/code> contains two plus quantifiers stacked on top of each other in the substring <code>'http++'<\/code>. Get rid of those and the code will run again!<\/p>\n<h2>Python Regex Quantifiers<\/h2>\n<p>The word &#8220;<a href=\"https:\/\/www.merriam-webster.com\/dictionary\/quantity\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">quantifier<\/a>&#8221; originates from latin: it&#8217;s meaning is <strong>quantus = how much \/ how often<\/strong>.<\/p>\n<p><strong>This is precisely what a regular expression quantifier means: you tell the regex engine how often you want to match a given pattern. <\/strong><\/p>\n<p>If you think you don&#8217;t define any quantifier, you do it implicitly: no quantifier means to match the regular expression exactly once.<\/p>\n<p>So what are the regex quantifiers in Python?<\/p>\n<figure class=\"wp-block-table is-style-stripes\">\n<table>\n<tbody>\n<tr>\n<td>Quantifier<\/td>\n<td>Meaning<\/td>\n<\/tr>\n<tr>\n<td><code>A?<\/code><\/td>\n<td>Match regular expression <code>A<\/code> zero or one times<\/td>\n<\/tr>\n<tr>\n<td><code>A*<\/code><\/td>\n<td>Match regular expression <code>A<\/code> zero or more times<\/td>\n<\/tr>\n<tr>\n<td><code>A+<\/code><\/td>\n<td>Match regular expression <code>A<\/code> one or more times<\/td>\n<\/tr>\n<tr>\n<td><code>A{m}<\/code><\/td>\n<td>Match regular expression <code>A<\/code> exactly m times<\/td>\n<\/tr>\n<tr>\n<td><code>A{m,n}<\/code><\/td>\n<td>Match regular expression <code>A<\/code> between m and n times (included)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>Note that in this tutorial, I assume you have at least a remote idea of what regular expressions actually are. If you haven&#8217;t, no problem, check out my <a rel=\"noreferrer noopener\" aria-label=\"detailed regex tutorial on this blog (opens in a new tab)\" href=\"https:\/\/blog.finxter.com\/python-regex\/\" target=\"_blank\">detailed regex tutorial on this blog<\/a>.<\/p>\n<p>You see in the table that the quantifiers <code>?<\/code>, <code>*<\/code>, <code>+<\/code>, <code>{m}<\/code>, and <code>{m,n}<\/code> define how often you repeat the matching of regex <code>A<\/code>. <\/p>\n<p>Let&#8217;s have a look at some examples&#8212;one for each quantifier:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">>>> import re\n>>> re.findall('a?', 'aaaa')\n['a', 'a', 'a', 'a', '']\n>>> re.findall('a*', 'aaaa')\n['aaaa', '']\n>>> re.findall('a+', 'aaaa')\n['aaaa']\n>>> re.findall('a{3}', 'aaaa')\n['aaa']\n>>> re.findall('a{1,2}', 'aaaa')\n['aa', 'aa']<\/pre>\n<p>In each line, you try a different quantifier on the same text <code>'aaaa'<\/code>. And, interestingly, each line leads to a different output:<\/p>\n<ul>\n<li>The <a rel=\"noreferrer noopener\" aria-label=\"zero-or-one (opens in a new tab)\" href=\"https:\/\/blog.finxter.com\/python-re-question-mark\/\" target=\"_blank\">zero-or-one<\/a> regex <code>'a?'<\/code> matches four times one <code>'a'<\/code>. Note that it doesn&#8217;t match zero characters if it can avoid doing so.<\/li>\n<li>The <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.finxter.com\/python-re-question-mark\/\" target=\"_blank\">zero-or-more<\/a> regex <code>'a*'<\/code> matches once four <code>'a'<\/code>s and consumes them. At the end of the string, it can still match the empty string.<\/li>\n<li>The <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.finxter.com\/python-re-question-mark\/\" target=\"_blank\">one-or-more<\/a> regex <code>'a+'<\/code> matches once four <code>'a'<\/code>s. In contrast to the previous quantifier, it cannot match an empty string.<\/li>\n<li>The repeating regex <code>'a{3}'<\/code> matches up to three <code>'a'<\/code>s in a single run. It can do so only once.<\/li>\n<li>The repeating regex <code>'a{1,2}'<\/code> matches one or two <code>'a'<\/code>s. It tries to match as many as possible.<\/li>\n<\/ul>\n<p>You&#8217;ve learned the basic quantifiers of Python regular expressions. <\/p>\n<h2>Where to Go From Here?<\/h2>\n<p>To summarize, you&#8217;ve learned that the multiple repeat error appears whenever you try to stack multiple quantifiers on top of each other. Avoid this and the error message will disappear. <\/p>\n<p>If you want to boost your Python regex skills to the next level, check out my free <a href=\"https:\/\/blog.finxter.com\/python-regex\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"in-depth regex superpower tutorial (20,000+) words (opens in a new tab)\">in-depth regex superpower tutorial (20,000+) words<\/a>. Or just bookmark the article for later read.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just like me an hour ago, you&#8217;re probably sitting in front of your regular expression code, puzzled by a strange error message: re.error: multiple repeat at position x How does it arise? Where does it come from? And, most importantly, how can you get rid of it? This article gives you answers to all of [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[857],"tags":[73,468,528],"class_list":["post-109764","post","type-post","status-publish","format-standard","hentry","category-python-tut","tag-programming","tag-python","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/109764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=109764"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/109764\/revisions"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=109764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=109764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=109764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}