Regex for a plus and minus sign, along with letters?

Viewed 432

I'm trying to write a Python function using the re library, essentially trying to extract the word that is within the brackets. These words contain letters, and some words contain a plus sign or minus sign (but not all). This is the function I have so far:

def processArray(array):
    newArray = []
    for i in array:
        m = re.search(r"\[([A-Za-z0-9\-\+]+)\]", i).groups()[0]
        newArray.append(m)

    return newArray

The array parameter passed in is [['Preconditions [+Here]\n'], ['Preconditions [+Is', '+The]\n'], ['Preconditions [-Example]\n']]. The newArray I hope to obtain is ['+Here', '-Is', '+The', '-Example']. With my current function, this is the error thrown out:

  File "file.py", line 71, in <module>
    preconditions = processArray(preconditions)
  File "file.py", line 29, in processArray
    m = re.search(r"\[([A-Za-z0-9\-\+]+)\]", i).groups()[0]
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/re.py", line 183, in search
    return _compile(pattern, flags).search(string)
TypeError: expected string or bytes-like object

Could anyone explain why this error is occurring and what I can do to fix it?

1 Answers

You may iterate over the lists inside the list and join all inner lists and use the following fix:

import re

def processArray(array):
    newArray = []
    for l in array:
        m = re.findall(r"[A-Za-z0-9+-]+(?=[^][]*])", " ".join(l))
        if m:
            newArray.extend(m)
    return newArray

print(processArray([['Preconditions [+Here]\n'], ['Preconditions [+Is', '+The]\n'], ['Preconditions [-Example]\n']]))
# => ['+Here', '+Is', '+The', '-Example']

See a Python demo.

The regex is [A-Za-z0-9+-]+(?=[^][]*]), it is a workaround to match one or more alphanumeric or -/+ chars only if followed with 0+ chars other than [ and ] up to a ]. It does not check for the open [. If it is necessary, you will have to run two regex operations:

def processArray(array):
    newArray = []
    for l in array:
        m = re.findall(r"\[(.*?)]", " ".join(l))
        for n in m:
            k = re.findall(r'[A-Za-z0-9+-]+', n)
            if k:
                newArray.extend(k)
    return newArray

See this Python demo, where the strings between parentheses are first extracted, and then the necessary matches inside them.

Related