russellmcdonell / pyDMNrules

An implementation of DMN (Decision Model Notation) in Python
Other
40 stars 9 forks source link

Added support for string contains() function. #8

Closed budney closed 2 years ago

budney commented 2 years ago

This is a small patch that adds support for the string contains() function. This isn't included in S-FEEL, but it's supported by pySFeel, and it's useful as heck.

russellmcdonell commented 2 years ago

You are right - I missed it. However there's a bit more to it, in order to be consistent with the other similar functions. Firstly, in a column about Surname you can have contains(Firstname, "russell") It's legal (dumb, but legal) and has to be supported. Also you can have not(contains("russell")) So, the a better patch is

    # Check for the known two parameter FEEL functions that return True or False
    match = re.match(r'^contains\((.*)\)$', thisTest)
    if not wasString and match is not None:           # if variable is a string, then check that it starts with this string
        # Check that there is only a single parameter
        withString = match.group(1)
        parameters = []
        try:
            for row in csv.reader([withString], dialect=csv.excel, doublequote=False, skipinitialspace=True, escapechar='\\'):
                parameters = list(row)
        except:
            pass
        if len(parameters) == 1:
            if withString[0] != '"':    # make sure the second arguement is a string
                withString = '"' + withString
            if withString[-1] != '"':
                withString += '"'
            if testIsNot:
                return self.data2sfeel(coordinate, sheet, 'not(contains(' + variable + ', ' + withString + '))', False)
            else:
                return self.data2sfeel(coordinate, sheet, 'contains(' + variable + ', ' + withString + ')', False)
        elif testIsNot:
            return self.data2sfeel(coordinate, sheet, 'not(' + thisTest + ')', False)
        else:
            return self.data2sfeel(coordinate, sheet, thisTest, False)
    match = re.match(r'^starts with\((.*)\)$', thisTest)

Which I will include in the next release.