Skip to content
Advertisement

How to match this part of the string with regex in Python without getting look-behind requires fixed-width pattern?

I want to extract the name from a create Table statement for example this:

“CREATE OR REPLACE TEMPORARY TABLE IF NOT EXISTS author (“

the name here is author. If you look into the official mariaDB documentation you will notice, that OR REPLACE, TEMPORARY and IF NOT EXISTS are optional parameters.

The regex I’ve come up with:

r"(?<=(create)s*(or replaces*)?(temporarys*)?(table)s*(if not existss*)?)(w+)(?=(s*)?(())"

There also is no upper limit of how many spaces need to be between each word, but there is at least one required.

When i try this regex on https://regexr.com/ it works with these examples(With flags case insensitive, multiline and global):

CREATE TABLE book (
CREATE OR REPLACE TABLE IF NOT EXISTS author(
CREATE OR REPLACE TEMPORARY TABLE IF NOT EXISTS publisher ( 

enter image description here enter image description here

However if i try to do this in python:

import re
firstRow = "CREATE OR REPLACE TABLE IF NOT EXISTS author ("
res = re.search(r"(?<=(create)s(or replaces)?(temporarys)?(table)s(if not existss)?)(w+)(?=(s)?(())", firstRow, re.IGNORECASE)

it throws following error message:

Traceback (most recent call last):
  File "test.py", line 116, in <module>
    res = re.sub(r"(?<=(create)s(or replaces)?(temporarys)?(table)s(if not existss)?)(w+)(?=(s)?(())", firstRow, re.IGNORECASE)
  File "C:UsersstefaAppDataLocalProgramsPythonPython38-32libre.py", line 210, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "C:UsersstefaAppDataLocalProgramsPythonPython38-32libre.py", line 304, in _compile
    p = sre_compile.compile(pattern, flags)
  File "C:UsersstefaAppDataLocalProgramsPythonPython38-32libsre_compile.py", line 768, in compile
    code = _code(p, flags)
  File "C:UsersstefaAppDataLocalProgramsPythonPython38-32libsre_compile.py", line 607, in _code
    _compile(code, p.data, flags)
  File "C:UsersstefaAppDataLocalProgramsPythonPython38-32libsre_compile.py", line 182, in _compile
    raise error("look-behind requires fixed-width pattern")
re.error: look-behind requires fixed-width pattern

Advertisement

Answer

It works as you have selected Javascript, which might support an infinite quantifier in a lookbehind assertion.

You don’t need any lookarounds at all as you are already using a capture group, so you can match what is around the table name.

As all the s* are optional, you might consider using word boundaries b to prevent partial word matches.

bcreatebs*(?:or replaces*(?:btemporarys*)?)?btables*(?:bif not existss*)?b(w+)s*(

Regex demo

Advertisement