|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2013 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the PyQt5 server part of the QRegularExpression wizzard. |
|
8 """ |
|
9 |
|
10 import json |
|
11 import sys |
|
12 |
|
13 |
|
14 def rxValidate(regexp, options): |
|
15 """ |
|
16 Function to validate the given regular expression. |
|
17 |
|
18 @param regexp regular expression to validate (string) |
|
19 @param options list of options (list of string) |
|
20 @return tuple of flag indicating validity (boolean), error |
|
21 string (string) and error offset (integer) |
|
22 """ |
|
23 try: |
|
24 from PyQt5.QtCore import QRegularExpression |
|
25 rxOptions = QRegularExpression.PatternOption.NoPatternOption |
|
26 if "CaseInsensitiveOption" in options: |
|
27 rxOptions |= QRegularExpression.PatternOption.CaseInsensitiveOption |
|
28 if "MultilineOption" in options: |
|
29 rxOptions |= QRegularExpression.PatternOption.MultilineOption |
|
30 if "DotMatchesEverythingOption" in options: |
|
31 rxOptions |= ( |
|
32 QRegularExpression.PatternOption.DotMatchesEverythingOption |
|
33 ) |
|
34 if "ExtendedPatternSyntaxOption" in options: |
|
35 rxOptions |= ( |
|
36 QRegularExpression.PatternOption.ExtendedPatternSyntaxOption |
|
37 ) |
|
38 if "InvertedGreedinessOption" in options: |
|
39 rxOptions |= ( |
|
40 QRegularExpression.PatternOption.InvertedGreedinessOption |
|
41 ) |
|
42 if "UseUnicodePropertiesOption" in options: |
|
43 rxOptions |= ( |
|
44 QRegularExpression.PatternOption.UseUnicodePropertiesOption |
|
45 ) |
|
46 if "DontCaptureOption" in options: |
|
47 rxOptions |= QRegularExpression.PatternOption.DontCaptureOption |
|
48 |
|
49 error = "" |
|
50 errorOffset = -1 |
|
51 re = QRegularExpression(regexp, rxOptions) |
|
52 valid = re.isValid() |
|
53 if not valid: |
|
54 error = re.errorString() |
|
55 errorOffset = re.patternErrorOffset() |
|
56 except ImportError: |
|
57 valid = False |
|
58 error = "ImportError" |
|
59 errorOffset = 0 |
|
60 |
|
61 return valid, error, errorOffset |
|
62 |
|
63 |
|
64 def rxExecute(regexp, options, text, startpos): |
|
65 """ |
|
66 Function to execute the given regular expression for a given text. |
|
67 |
|
68 @param regexp regular expression to validate (string) |
|
69 @param options list of options (list of string) |
|
70 @param text text to execute on (string) |
|
71 @param startpos start position for the execution (integer) |
|
72 @return tuple of a flag indicating a successful match (boolean) and |
|
73 a list of captures containing the complete match as matched string |
|
74 (string), match start (integer), match end (integer) and match length |
|
75 (integer) for each entry |
|
76 """ |
|
77 valid, error, errorOffset = rxValidate(regexp, options) |
|
78 if not valid: |
|
79 return valid, error, errorOffset |
|
80 |
|
81 from PyQt5.QtCore import QRegularExpression |
|
82 rxOptions = QRegularExpression.PatternOption.NoPatternOption |
|
83 if "CaseInsensitiveOption" in options: |
|
84 rxOptions |= QRegularExpression.PatternOption.CaseInsensitiveOption |
|
85 if "MultilineOption" in options: |
|
86 rxOptions |= QRegularExpression.PatternOption.MultilineOption |
|
87 if "DotMatchesEverythingOption" in options: |
|
88 rxOptions |= ( |
|
89 QRegularExpression.PatternOption.DotMatchesEverythingOption |
|
90 ) |
|
91 if "ExtendedPatternSyntaxOption" in options: |
|
92 rxOptions |= ( |
|
93 QRegularExpression.PatternOption.ExtendedPatternSyntaxOption |
|
94 ) |
|
95 if "InvertedGreedinessOption" in options: |
|
96 rxOptions |= QRegularExpression.PatternOption.InvertedGreedinessOption |
|
97 if "UseUnicodePropertiesOption" in options: |
|
98 rxOptions |= ( |
|
99 QRegularExpression.PatternOption.UseUnicodePropertiesOption |
|
100 ) |
|
101 if "DontCaptureOption" in options: |
|
102 rxOptions |= QRegularExpression.PatternOption.DontCaptureOption |
|
103 |
|
104 matched = False |
|
105 captures = [] |
|
106 re = QRegularExpression(regexp, rxOptions) |
|
107 match = re.match(text, startpos) |
|
108 if match.hasMatch(): |
|
109 matched = True |
|
110 for index in range(match.lastCapturedIndex() + 1): |
|
111 captures.append([ |
|
112 match.captured(index), |
|
113 match.capturedStart(index), |
|
114 match.capturedEnd(index), |
|
115 match.capturedLength(index) |
|
116 ]) |
|
117 |
|
118 return matched, captures |
|
119 |
|
120 |
|
121 def main(): |
|
122 """ |
|
123 Function containing the main routine. |
|
124 """ |
|
125 while True: |
|
126 commandStr = sys.stdin.readline() |
|
127 try: |
|
128 commandDict = json.loads(commandStr) |
|
129 responseDict = {"error": ""} |
|
130 if "command" in commandDict: |
|
131 command = commandDict["command"] |
|
132 if command == "exit": |
|
133 break |
|
134 elif command == "available": |
|
135 try: |
|
136 import PyQt5 # __IGNORE_WARNING__ |
|
137 responseDict["available"] = True |
|
138 except ImportError: |
|
139 responseDict["available"] = False |
|
140 elif command == "validate": |
|
141 valid, error, errorOffset = rxValidate( |
|
142 commandDict["regexp"], commandDict["options"]) |
|
143 responseDict["valid"] = valid |
|
144 responseDict["errorMessage"] = error |
|
145 responseDict["errorOffset"] = errorOffset |
|
146 elif command == "execute": |
|
147 valid, error, errorOffset = rxValidate( |
|
148 commandDict["regexp"], commandDict["options"]) |
|
149 if not valid: |
|
150 responseDict["valid"] = valid |
|
151 responseDict["errorMessage"] = error |
|
152 responseDict["errorOffset"] = errorOffset |
|
153 else: |
|
154 matched, captures = rxExecute( |
|
155 commandDict["regexp"], commandDict["options"], |
|
156 commandDict["text"], commandDict["startpos"]) |
|
157 responseDict["matched"] = matched |
|
158 responseDict["captures"] = captures |
|
159 except ValueError as err: |
|
160 responseDict = {"error": str(err)} |
|
161 except Exception as err: |
|
162 responseDict = {"error": str(err)} |
|
163 responseStr = json.dumps(responseDict) |
|
164 sys.stdout.write(responseStr) |
|
165 sys.stdout.flush() |
|
166 |
|
167 sys.exit(0) |
|
168 |
|
169 |
|
170 if __name__ == "__main__": |
|
171 main() |