Finding + sign using regex, how to fix SyntaxWarning

I have Python 3.14.0 on Windows 11.

I have this line where I want to search for an optional + sign in variable lin.

if re.search(r'upch2026\+?', lin, re.IGNORECASE):

But I’m getting a SyntaxWarning from Python: Warning: SyntaxWarning: "\+" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\+"? A raw string is also an option. if '<upch2026\+?;' in lin:

The strings I’m looking for are upch2026 or upch2026+. They get processed the same way.

  1. What does this warning mean?
  2. Isn’t it possible to find a plus sign using re.search()?
  3. Is there a better way to code this regex?
  4. Is if '<upch2026\+?;' in lin: actually a regex so the + sign is optional?

Thank you.

The specific example is possible without re, e.g. using str.partition("upch2026").

I’m not sure what’s going on with your Python though. I’m also on Windows 11:

Python 3.14.1 (tags/v3.14.1:57e0d17, Dec  2 2025, 14:05:07) [MSC v.1944 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> if re.search(r'upch2026\+?', lin, re.IGNORECASE): pass
...
>>>

3.14.3 is fine too (both from uv)

Python 3.14.3 (main, Mar 10 2026, 18:14:48) [MSC v.1944 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import re; lin="upch2026"
>>> if re.search(r'upch2026\+?', lin, re.IGNORECASE): pass

No warning in command lines scripts either. Maybe mine are different builds?

I have clarified my original post that I’m on 3.14.0. I wonder if this was a bug.

I managed to fix this by using a character class like: if re.search('r<upch2026[+]?', lin, re.IGNORECASE):

But the odd behavior remains.

1 Like

So it says “A raw string is also an option” even though you are using a raw string?

Python suggested a raw string like this but no r qualifier was used:

 if ‘<upch2026+?;’ in lin:

but I don’t know if in supports regex. This search pattern has to be a regex as I’m looking for both <upch2026 and <upch2026+ in the variable lin.

Um… Looking at your raw message, I see this:

But I'm getting a SyntaxWarning from Python: Warning:  SyntaxWarning: "\+" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\+"? A raw string is also an option. if '<upch2026\+?;' in lin:

Note the differences, and please use proper formatting to avoid them.

But the odd behavior remains.

Behaviour probably will remain the same on old patch versions. But perhaps it’s been fixed in 3.14.1 onwards, and the problem will go away if you upgrade to 3.14.3?

Actually that actual error output seems to not talk about your if re.search(r'upch2026\+?', lin, re.IGNORECASE): line but about your if '<upch2026\+?;' in lin:.

1 Like

OK I have reproduced it. But only by replacing '...' with r'...'. Are you quite sure the line you’ve quoted is exactly the one that triggers the error?

If nothing else, please make sure you use raw-strings for regex patterns in future, like we all should.

>python -ic "import re"
>>> if re.search('upch2026\+?', "", re.IGNORECASE): pass
...
<python-input-0>:1: SyntaxWarning: "\+" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\+"? A raw string is also an option.
>>> import sys; print(sys.version)
3.14.1 (tags/v3.14.1:57e0d17, Dec  2 2025, 14:05:07) [MSC v.1944 64 bit (AMD64)]
1 Like

This is confusing in part because the Discourse Markdown language also treats backslash as an escape character, so some of the things you typed (or pasted) aren’t what we see. If you want us to see a backslash, you generally have to spell it in Markdown as two adjacent backslashes.

In any case, regular strings do their own backslash processing in Python, and are restricted to specific sequences. Else they’ll trigger a syntax warning (which will eventually become errors). For example, this is completely expected:

>>> '\+'
<python-input-16>:1: SyntaxWarning: "\+" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\+"? A raw string is also an option.

Which is a lot like the warning you showed us.. But note that it said “a raw string is also an option”. Raw strings (strings with a letter “r” prefix before the opening quote) do not try to perform backslash escapes. A backslash is just another character to them. So this is also expected:

>>> r'\+'
'\\+'

The raw string left the backslash alone, which, when the interpreter displays the result as a regular string, is shown as a doubled backslash. Because double backslash is the way to put a single backlash in a regular (not raw) string. A doubled backslash is itself a valid escape sequence in regular strings, and is translated to a single backslash

So something’s off here. The warning message you got suggested using a raw string instead - but the code you showed us was already using a raw string. It’s also suspicious that the warning you showed us ended with

 if ‘<upch2026+?;’ in lin:

which is not all the re.search line you said triggered the warning.

I assume that’s not what you typed though - that Markdown ate a backslash you actually entered, and that what you really typed was

 if ‘<upch2026\+?;’ in lin:

That should trigger a warning, because “backslash plus” is not a valid escape sequence.

So please triple-check what DIscourse actually displays, and edit your post until it shows what you intended it to show.

Nope. That’s just a plain string search, nothing to do with regexps.

3 Likes

Sorry, as noted above by another person I have just quoted the error message as code to properly show the error message, in my original message. Please reload this page.

I have reloaded it. I’ve installed 3.14.0. No such error occurs with a proper raw string (r"abc\+def").

  • Supply an MRX.
  • Double check which type of string you’re using.
  • Upgrade to Python 3.14.3

Until then, the evidence looks to me that this is simply a typo of yours.

1 Like

You’re right. This is bizarre. Here’s what I got to work now:

if re.search(r'upch2026\+?', lin, re.IGNORECASE):

Here’s my original statement copied from the first post in this thread:
if re.search(r'upch2026\+?', lin, re.IGNORECASE):

I get no SyntaxWarning now. I don’t see the difference, but it works.

Thanks for everyone’s help!

1 Like

What’s an MRX? I’d like to learn something new today. :slight_smile:

1 Like

Glad you fixed it - well done. I think adjusting re.search(r' to re.search(', will reproduce the warning - it’s changing the raw string literal into a standard string literal.

I’m sorry if the acronym’s not caught on yet and it’s only me that calls them MRXs. But I use that to mean Minimal Reproducible Example

2 Likes