Last active
December 11, 2021 16:01
-
-
Save stevewadsworth/85ef8f63d4dd177b6da7a573558d5db2 to your computer and use it in GitHub Desktop.
Regex to match and|or with minimal match to left and maximal to right
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // regex to match and|or with minimal match to left and maximal to right /^\s*(.+?)\s+(or|and)\s+(.+?)\s*$/ | |
| // foo = 192.168.0.1 or foo = 192.168.0.110 and bar = baz | |
| // Gives "foo = 192.168.0.1", "or", "foo = 192.168.0.110 and bar = baz" | |
| // The third match is ready to be re-input to the regex | |
| // ...Or should it be the other way around with the maximal match on the left for correct left to right associativity? | |
| // Not sure right now, so keep it in mind removing the ? from (.+?) will do it /^\s*(.+)\s+(or|and)\s+(.+?)\s*$/ | |
| // | |
| // regex to match '=' /(\S+)\s*(=)\s*(\S+)/ | |
| // foo = 192.168.0.1 | |
| // Gives "foo", "=", "192.168.0.1" | |
| const LOGICAL_OPERATORS = /^\s*(.+?)\s+(or|and)\s+(.+?)\s*$/; | |
| const NOT_EQUALS = /^\s*(\S+)\s*(!=)\s*(\S+)\s*$/; | |
| const GREATER_OR_EQUALS = /^\s*(\S+)\s*(>=)\s*(\S+)\s*$/; | |
| const LESS_OR_EQUALS = /^\s*(\S+)\s*(<=)\s*(\S+)\s*$/; | |
| const EQUALS = /^\s*(\S+)\s*(=)\s*(\S+)\s*$/; | |
| const GREATER = /^\s*(\S+)\s*(>)\s*(\S+)\s*$/; | |
| const LESS = /^\s*(\S+)\s*(<)\s*(\S+)\s*$/; | |
| // The order of the operators are critical. More specific to less specific! | |
| const operators = [ | |
| NOT_EQUALS, | |
| GREATER_OR_EQUALS, | |
| LESS_OR_EQUALS, | |
| EQUALS, | |
| GREATER, | |
| LESS | |
| ]; | |
| export class QueryTree { | |
| lValue: QueryTree|string; | |
| rValue: QueryTree|string; | |
| operator: string; | |
| isLeaf: boolean; | |
| isValid: boolean = false; | |
| constructor(queryString: string) { | |
| // First match logical operators | |
| const match = queryString.match(LOGICAL_OPERATORS); | |
| if (match) { | |
| this.lValue = new QueryTree(match[1]); | |
| this.operator = match[2]; | |
| this.rValue = new QueryTree(match[3]); | |
| // A logical node cannot be a leaf | |
| this.isLeaf = false; | |
| // This node is only valid if all it's children are valid | |
| this.isValid = this.lValue.isValid && this.rValue.isValid; | |
| } else { | |
| for (let i = 0; i < operators.length; i++) { | |
| const operator = operators[i]; | |
| const match = queryString.match(operator); | |
| if (match) { | |
| // Got a leaf match | |
| this.isLeaf = true; | |
| this.isValid = true; | |
| this.lValue = match[1]; | |
| this.operator = match[2]; | |
| this.rValue = match[3]; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment