简体   繁体   中英

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 replace\s*)?(temporary\s*)?(table)\s*(if not exists\s*)?)(\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 ( 

在此处输入图像描述 在此处输入图像描述

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 replace\s)?(temporary\s)?(table)\s(if not exists\s)?)(\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 replace\s)?(temporary\s)?(table)\s(if not exists\s)?)(\w+)(?=(\s)?(\())", firstRow, re.IGNORECASE)
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python38-32\lib\re.py", line 210, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python38-32\lib\re.py", line 304, in _compile
    p = sre_compile.compile(pattern, flags)
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python38-32\lib\sre_compile.py", line 768, in compile
    code = _code(p, flags)
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python38-32\lib\sre_compile.py", line 607, in _code
    _compile(code, p.data, flags)
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python38-32\lib\sre_compile.py", line 182, in _compile
    raise error("look-behind requires fixed-width pattern")
re.error: look-behind requires fixed-width pattern

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.

\bcreate\b\s*(?:or replace\s*(?:\btemporary\s*)?)?\btable\s*(?:\bif not exists\s*)?\b(\w+)\s*\(

Regex demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM