We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
escaping stuff: scrutinizer issues
https://scrutinizer-ci.com/g/coala-analyzer/coala/inspections/8589a071-2905-40dd-a562-bfae3b8f40e5/issues/

need to fix after merging the escaping stuff


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `coalib/parsing/StringProcessing.py`
Content:
```
1 import re
2 
3 
4 def search_for(pattern, string, flags=0, max_match=0):
5     """
6     Searches for a given pattern in a string.
7 
8     :param pattern:   A regex pattern that defines what to match.
9     :param string:    The string to search in.
10     :param flags:     Additional flags to pass to the regex processor.
11     :param max_match: Defines the maximum number of matches to perform. If 0 or
12                       less is provided, the number of splits is not limited.
13     :return:          An iterator returning MatchObject's.
14     """
15     for elem in limit(re.finditer(pattern, string, flags), max_match):
16         yield elem
17 
18 
19 def limit(iterator, count):
20     """
21     A filter that removes all elements behind the set limit.
22 
23     :param iterator: The iterator to be filtered.
24     :param count:    The iterator limit. All elements at positions bigger than
25                      this limit are trimmed off. Exclusion: 0 or numbers below
26                      does not limit at all, means the passed iterator is
27                      completely yielded.
28     """
29     if count <= 0:  # Performance branch
30         for elem in iterator:
31             yield elem
32     else:
33         for elem in iterator:
34             yield elem
35             count -= 1
36             if count == 0:
37                 break
38 
39 
40 def trim_empty_matches(iterator, groups=[0]):
41     """
42     A filter that removes empty match strings. It can only operate on iterators
43     whose elements are of type MatchObject.
44 
45     :param iterator: The iterator to be filtered.
46     :param groups:   An iteratable defining the groups to check for blankness.
47                      Only results are not yielded if all groups of the match
48                      are blank.
49                      You can not only pass numbers but also strings, if your
50                      MatchObject contains named groups.
51     """
52     for elem in iterator:
53         for group in groups:
54             if len(elem.group(group)) != 0:
55                 yield elem
56 
57                 continue
58 
59 
60 def split(pattern,
61           string,
62           max_split=0,
63           remove_empty_matches=False):
64     """
65     Splits the given string by the specified pattern. The return character (\n)
66     is not a natural split pattern (if you don't specify it yourself).
67     This function ignores escape sequences.
68 
69     :param pattern:              A regex pattern that defines where to split.
70     :param string:               The string to split by the defined pattern.
71     :param max_split:            Defines the maximum number of splits. If 0 or
72                                  less is provided, the number of splits is not
73                                  limited.
74     :param remove_empty_matches: Defines whether empty entries should
75                                  be removed from the result.
76     :return:                     An iterator returning the split up strings.
77     """
78     # re.split() is not usable for this function. It has a bug when using too
79     # many capturing groups "()".
80 
81     # Regex explanation:
82     # 1. (.*?)              Match any char unlimited times, as few times as
83     #                       possible. Save the match in the first capturing
84     #                       group (match.group(1)).
85     # 2. (?:pattern)        A non-capturing group that matches the
86     #                       split-pattern. Because the first group is lazy
87     #                       (matches as few times as possible) the next
88     #                       occurring split-sequence is matched.
89     regex = r"(.*?)(?:" + pattern + r")"
90 
91     item = None
92     for item in re.finditer(regex, string, re.DOTALL):
93         if not remove_empty_matches or len(item.group(1)) != 0:
94             # Return the first matching group. The pattern from parameter can't
95             # change the group order.
96             yield item.group(1)
97 
98             max_split -= 1
99             if 0 == max_split:
100                 break  # only reachable when max_split > 0
101 
102     if item is None:
103         last_pos = 0
104     else:
105         last_pos = item.end()
106 
107     # Append the rest of the string, since it's not in the result list (only
108     # matches are captured that have a leading separator).
109     if not remove_empty_matches or len(string) > last_pos:
110         yield string[last_pos:]
111 
112 
113 def unescaped_split(pattern,
114                     string,
115                     max_split=0,
116                     remove_empty_matches=False):
117     """
118     Splits the given string by the specified pattern. The return character (\n)
119     is not a natural split pattern (if you don't specify it yourself).
120     This function handles escaped split-patterns (and so splits only patterns
121     that are unescaped).
122     CAUTION: Using the escaped character '\' in the pattern the function can
123              return strange results. The backslash can interfere with the
124              escaping regex-sequence used internally to split.
125 
126     :param pattern:              A regex pattern that defines where to split.
127     :param string:               The string to split by the defined pattern.
128     :param max_split:            Defines the maximum number of splits. If 0 or
129                                  less is provided, the number of splits is not
130                                  limited.
131     :param remove_empty_matches: Defines whether empty entries should
132                                  be removed from the result.
133     :return:                     An iterator returning the split up strings.
134     """
135     # Need to use re.search() since using splitting directly is not possible.
136     # We need to match the separator only if the number of escapes is even.
137     # The solution is to use look-behind-assertions, but these don't support a
138     # variable number of letters (means quantifiers are not usable there). So
139     # if we try to match the escape sequences too, they would be replaced,
140     # because they are consumed then by the regex. That's not wanted.
141 
142     # Regex explanation:
143     # 1. (.*?)              Match any char unlimited times, as few times as
144     #                       possible. Save the match in the first capturing
145     #                       group (match.group(1)).
146     # 2. (?<!\\)((?:\\\\)*) Unescaping sequence. Only matches backslashes if
147     #                       their count is even.
148     # 3. (?:pattern)        A non-capturing group that matches the
149     #                       split-pattern. Because the first group is lazy
150     #                       (matches as few times as possible) the next
151     #                       occurring split-sequence is matched.
152     regex = r"(.*?)(?<!\\)((?:\\\\)*)(?:" + pattern + r")"
153 
154     item = None
155     for item in re.finditer(regex, string, re.DOTALL):
156         concat_string = item.group(1)
157 
158         if item.group(2) is not None:
159             # Escaped escapes were consumed from the second group, append them
160             # too.
161             concat_string += item.group(2)
162 
163         if not remove_empty_matches or len(concat_string) != 0:
164             # Return the first matching group. The pattern from parameter can't
165             # change the group order.
166             yield concat_string
167 
168             max_split -= 1
169             if max_split == 0:
170                 break  # only reachable when max_split > 0
171 
172     if item is None:
173         last_pos = 0
174     else:
175         last_pos = item.end()
176 
177     # Append the rest of the string, since it's not in the result list (only
178     # matches are captured that have a leading separator).
179     if not remove_empty_matches or len(string) > last_pos:
180         yield string[last_pos:]
181 
182 
183 def search_in_between(begin,
184                       end,
185                       string,
186                       max_matches=0,
187                       remove_empty_matches=False):
188     """
189     Searches for a string enclosed between a specified begin- and end-sequence.
190     Also enclosed \n are put into the result. Doesn't handle escape sequences.
191 
192     :param begin:                A regex pattern that defines where to start
193                                  matching.
194     :param end:                  A regex pattern that defines where to end
195                                  matching.
196     :param string:               The string where to search in.
197     :param max_matches           Defines the maximum number of matches. If 0 or
198                                  less is provided, the number of splits is not
199                                  limited.
200     :param remove_empty_matches: Defines whether empty entries should
201                                  be removed from the result.
202     :return:                     An iterator returning the matched strings.
203     """
204 
205     # Compilation of the begin sequence is needed to get the number of
206     # capturing groups in it.
207     compiled_begin_pattern = re.compile(begin)
208 
209     # Regex explanation:
210     # 1. (?:begin) A non-capturing group that matches the begin sequence.
211     # 2. (.*?)     Match any char unlimited times, as few times as possible.
212     #              Save the match in the first capturing group
213     #              (match.group(1)).
214     # 3. (?:end)   A non-capturing group that matches the end sequence.
215     #              Because the previous group is lazy (matches as few times as
216     #              possible) the next occurring end-sequence is matched.
217     regex = r"(?:" + begin + r")(.*?)(?:" + end + r")"
218 
219     matches = re.finditer(regex, string, re.DOTALL)
220 
221     if remove_empty_matches:
222         matches = trim_empty_matches(matches,
223                                      [compiled_begin_pattern.groups + 1])
224 
225     matches = limit(matches, max_matches)
226 
227     for elem in matches:
228         yield elem.group(compiled_begin_pattern.groups + 1)
229 
230 
231 def unescaped_search_in_between(begin,
232                                 end,
233                                 string,
234                                 max_matches=0,
235                                 remove_empty_matches=False):
236     """
237     Searches for a string enclosed between a specified begin- and end-sequence.
238     Also enclosed \n are put into the result.
239     Handles escaped begin- and end-sequences (and so only patterns that are
240     unescaped).
241     CAUTION: Using the escaped character '\' in the begin- or end-sequences
242              the function can return strange results. The backslash can
243              interfere with the escaping regex-sequence used internally to
244              match the enclosed string.
245 
246     :param begin:                The begin-sequence where to start matching.
247                                  Providing regexes (and not only fixed strings)
248                                  is allowed.
249     :param end:                  The end-sequence where to end matching.
250                                  Providing regexes (and not only fixed strings)
251                                  is allowed.
252     :param string:               The string where to search in.
253     :param max_matches           Defines the maximum number of matches. If 0 or
254                                  less is provided, the number of splits is not
255                                  limited.
256     :param remove_empty_matches: Defines whether empty entries should
257                                  be removed from the result.
258     :return:                     An iterator returning the matched strings.
259     """
260     # Compilation of the begin sequence is needed to get the number of
261     # capturing groups in it.
262     compiled_begin_pattern = re.compile(begin)
263 
264     # Regex explanation:
265     # 1. (?<!\\)(?:\\\\)* Unescapes the following char. The first part of this
266     #                     regex is a look-behind assertion. Only match the
267     #                     following if no single backslash is before it.
268     #                     The second part matches all double backslashes.
269     #                     In fact this sequence matches all escapes that occur
270     #                     as a multiple of two, means the following statement
271     #                     is not escaped.
272     # 2. (?:begin)        A non-capturing group that matches the begin
273     # 3. (.*?)            sequence. Match any char unlimited times, as few
274     #                     times as possible. Save the match in the capturing
275     #                     group after all capturing groups that can appear in
276     #                     'begin'.
277     # 4. (?<!\\)(?:\\\\)* Again the unescaping regex.
278     # 5. (?:end)          A non-capturing group that matches the end sequence.
279     #                     Because the 3. group is lazy (matches as few times as
280     #                     possible) the next occurring end-sequence is matched.
281     regex = (r"(?<!\\)(?:\\\\)*(?:" + begin + r")(.*?)(?<!\\)((?:\\\\)*)(?:" +
282              end + r")")
283 
284     matches = re.finditer(regex, string, re.DOTALL)
285 
286     if remove_empty_matches:
287         matches = trim_empty_matches(matches,
288                                      [compiled_begin_pattern.groups + 1,
289                                       compiled_begin_pattern.groups + 2])
290 
291     matches = limit(matches, max_matches)
292 
293     for elem in matches:
294         yield (elem.group(compiled_begin_pattern.groups + 1) +
295                elem.group(compiled_begin_pattern.groups + 2))
296
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/coalib/parsing/StringProcessing.py b/coalib/parsing/StringProcessing.py
--- a/coalib/parsing/StringProcessing.py
+++ b/coalib/parsing/StringProcessing.py
@@ -53,7 +53,6 @@
         for group in groups:
             if len(elem.group(group)) != 0:
                 yield elem
-
                 continue

{"golden_diff": "diff --git a/coalib/parsing/StringProcessing.py b/coalib/parsing/StringProcessing.py\n--- a/coalib/parsing/StringProcessing.py\n+++ b/coalib/parsing/StringProcessing.py\n@@ -53,7 +53,6 @@\n         for group in groups:\n             if len(elem.group(group)) != 0:\n                 yield elem\n-\n                 continue\n", "issue": "escaping stuff: scrutinizer issues\nhttps://scrutinizer-ci.com/g/coala-analyzer/coala/inspections/8589a071-2905-40dd-a562-bfae3b8f40e5/issues/\n\nneed to fix after merging the escaping stuff\n\n", "before_files": [{"content": "import re\n\n\ndef search_for(pattern, string, flags=0, max_match=0):\n    \"\"\"\n    Searches for a given pattern in a string.\n\n    :param pattern:   A regex pattern that defines what to match.\n    :param string:    The string to search in.\n    :param flags:     Additional flags to pass to the regex processor.\n    :param max_match: Defines the maximum number of matches to perform. If 0 or\n                      less is provided, the number of splits is not limited.\n    :return:          An iterator returning MatchObject's.\n    \"\"\"\n    for elem in limit(re.finditer(pattern, string, flags), max_match):\n        yield elem\n\n\ndef limit(iterator, count):\n    \"\"\"\n    A filter that removes all elements behind the set limit.\n\n    :param iterator: The iterator to be filtered.\n    :param count:    The iterator limit. All elements at positions bigger than\n                     this limit are trimmed off. Exclusion: 0 or numbers below\n                     does not limit at all, means the passed iterator is\n                     completely yielded.\n    \"\"\"\n    if count <= 0:  # Performance branch\n        for elem in iterator:\n            yield elem\n    else:\n        for elem in iterator:\n            yield elem\n            count -= 1\n            if count == 0:\n                break\n\n\ndef trim_empty_matches(iterator, groups=[0]):\n    \"\"\"\n    A filter that removes empty match strings. It can only operate on iterators\n    whose elements are of type MatchObject.\n\n    :param iterator: The iterator to be filtered.\n    :param groups:   An iteratable defining the groups to check for blankness.\n                     Only results are not yielded if all groups of the match\n                     are blank.\n                     You can not only pass numbers but also strings, if your\n                     MatchObject contains named groups.\n    \"\"\"\n    for elem in iterator:\n        for group in groups:\n            if len(elem.group(group)) != 0:\n                yield elem\n\n                continue\n\n\ndef split(pattern,\n          string,\n          max_split=0,\n          remove_empty_matches=False):\n    \"\"\"\n    Splits the given string by the specified pattern. The return character (\\n)\n    is not a natural split pattern (if you don't specify it yourself).\n    This function ignores escape sequences.\n\n    :param pattern:              A regex pattern that defines where to split.\n    :param string:               The string to split by the defined pattern.\n    :param max_split:            Defines the maximum number of splits. If 0 or\n                                 less is provided, the number of splits is not\n                                 limited.\n    :param remove_empty_matches: Defines whether empty entries should\n                                 be removed from the result.\n    :return:                     An iterator returning the split up strings.\n    \"\"\"\n    # re.split() is not usable for this function. It has a bug when using too\n    # many capturing groups \"()\".\n\n    # Regex explanation:\n    # 1. (.*?)              Match any char unlimited times, as few times as\n    #                       possible. Save the match in the first capturing\n    #                       group (match.group(1)).\n    # 2. (?:pattern)        A non-capturing group that matches the\n    #                       split-pattern. Because the first group is lazy\n    #                       (matches as few times as possible) the next\n    #                       occurring split-sequence is matched.\n    regex = r\"(.*?)(?:\" + pattern + r\")\"\n\n    item = None\n    for item in re.finditer(regex, string, re.DOTALL):\n        if not remove_empty_matches or len(item.group(1)) != 0:\n            # Return the first matching group. The pattern from parameter can't\n            # change the group order.\n            yield item.group(1)\n\n            max_split -= 1\n            if 0 == max_split:\n                break  # only reachable when max_split > 0\n\n    if item is None:\n        last_pos = 0\n    else:\n        last_pos = item.end()\n\n    # Append the rest of the string, since it's not in the result list (only\n    # matches are captured that have a leading separator).\n    if not remove_empty_matches or len(string) > last_pos:\n        yield string[last_pos:]\n\n\ndef unescaped_split(pattern,\n                    string,\n                    max_split=0,\n                    remove_empty_matches=False):\n    \"\"\"\n    Splits the given string by the specified pattern. The return character (\\n)\n    is not a natural split pattern (if you don't specify it yourself).\n    This function handles escaped split-patterns (and so splits only patterns\n    that are unescaped).\n    CAUTION: Using the escaped character '\\' in the pattern the function can\n             return strange results. The backslash can interfere with the\n             escaping regex-sequence used internally to split.\n\n    :param pattern:              A regex pattern that defines where to split.\n    :param string:               The string to split by the defined pattern.\n    :param max_split:            Defines the maximum number of splits. If 0 or\n                                 less is provided, the number of splits is not\n                                 limited.\n    :param remove_empty_matches: Defines whether empty entries should\n                                 be removed from the result.\n    :return:                     An iterator returning the split up strings.\n    \"\"\"\n    # Need to use re.search() since using splitting directly is not possible.\n    # We need to match the separator only if the number of escapes is even.\n    # The solution is to use look-behind-assertions, but these don't support a\n    # variable number of letters (means quantifiers are not usable there). So\n    # if we try to match the escape sequences too, they would be replaced,\n    # because they are consumed then by the regex. That's not wanted.\n\n    # Regex explanation:\n    # 1. (.*?)              Match any char unlimited times, as few times as\n    #                       possible. Save the match in the first capturing\n    #                       group (match.group(1)).\n    # 2. (?<!\\\\)((?:\\\\\\\\)*) Unescaping sequence. Only matches backslashes if\n    #                       their count is even.\n    # 3. (?:pattern)        A non-capturing group that matches the\n    #                       split-pattern. Because the first group is lazy\n    #                       (matches as few times as possible) the next\n    #                       occurring split-sequence is matched.\n    regex = r\"(.*?)(?<!\\\\)((?:\\\\\\\\)*)(?:\" + pattern + r\")\"\n\n    item = None\n    for item in re.finditer(regex, string, re.DOTALL):\n        concat_string = item.group(1)\n\n        if item.group(2) is not None:\n            # Escaped escapes were consumed from the second group, append them\n            # too.\n            concat_string += item.group(2)\n\n        if not remove_empty_matches or len(concat_string) != 0:\n            # Return the first matching group. The pattern from parameter can't\n            # change the group order.\n            yield concat_string\n\n            max_split -= 1\n            if max_split == 0:\n                break  # only reachable when max_split > 0\n\n    if item is None:\n        last_pos = 0\n    else:\n        last_pos = item.end()\n\n    # Append the rest of the string, since it's not in the result list (only\n    # matches are captured that have a leading separator).\n    if not remove_empty_matches or len(string) > last_pos:\n        yield string[last_pos:]\n\n\ndef search_in_between(begin,\n                      end,\n                      string,\n                      max_matches=0,\n                      remove_empty_matches=False):\n    \"\"\"\n    Searches for a string enclosed between a specified begin- and end-sequence.\n    Also enclosed \\n are put into the result. Doesn't handle escape sequences.\n\n    :param begin:                A regex pattern that defines where to start\n                                 matching.\n    :param end:                  A regex pattern that defines where to end\n                                 matching.\n    :param string:               The string where to search in.\n    :param max_matches           Defines the maximum number of matches. If 0 or\n                                 less is provided, the number of splits is not\n                                 limited.\n    :param remove_empty_matches: Defines whether empty entries should\n                                 be removed from the result.\n    :return:                     An iterator returning the matched strings.\n    \"\"\"\n\n    # Compilation of the begin sequence is needed to get the number of\n    # capturing groups in it.\n    compiled_begin_pattern = re.compile(begin)\n\n    # Regex explanation:\n    # 1. (?:begin) A non-capturing group that matches the begin sequence.\n    # 2. (.*?)     Match any char unlimited times, as few times as possible.\n    #              Save the match in the first capturing group\n    #              (match.group(1)).\n    # 3. (?:end)   A non-capturing group that matches the end sequence.\n    #              Because the previous group is lazy (matches as few times as\n    #              possible) the next occurring end-sequence is matched.\n    regex = r\"(?:\" + begin + r\")(.*?)(?:\" + end + r\")\"\n\n    matches = re.finditer(regex, string, re.DOTALL)\n\n    if remove_empty_matches:\n        matches = trim_empty_matches(matches,\n                                     [compiled_begin_pattern.groups + 1])\n\n    matches = limit(matches, max_matches)\n\n    for elem in matches:\n        yield elem.group(compiled_begin_pattern.groups + 1)\n\n\ndef unescaped_search_in_between(begin,\n                                end,\n                                string,\n                                max_matches=0,\n                                remove_empty_matches=False):\n    \"\"\"\n    Searches for a string enclosed between a specified begin- and end-sequence.\n    Also enclosed \\n are put into the result.\n    Handles escaped begin- and end-sequences (and so only patterns that are\n    unescaped).\n    CAUTION: Using the escaped character '\\' in the begin- or end-sequences\n             the function can return strange results. The backslash can\n             interfere with the escaping regex-sequence used internally to\n             match the enclosed string.\n\n    :param begin:                The begin-sequence where to start matching.\n                                 Providing regexes (and not only fixed strings)\n                                 is allowed.\n    :param end:                  The end-sequence where to end matching.\n                                 Providing regexes (and not only fixed strings)\n                                 is allowed.\n    :param string:               The string where to search in.\n    :param max_matches           Defines the maximum number of matches. If 0 or\n                                 less is provided, the number of splits is not\n                                 limited.\n    :param remove_empty_matches: Defines whether empty entries should\n                                 be removed from the result.\n    :return:                     An iterator returning the matched strings.\n    \"\"\"\n    # Compilation of the begin sequence is needed to get the number of\n    # capturing groups in it.\n    compiled_begin_pattern = re.compile(begin)\n\n    # Regex explanation:\n    # 1. (?<!\\\\)(?:\\\\\\\\)* Unescapes the following char. The first part of this\n    #                     regex is a look-behind assertion. Only match the\n    #                     following if no single backslash is before it.\n    #                     The second part matches all double backslashes.\n    #                     In fact this sequence matches all escapes that occur\n    #                     as a multiple of two, means the following statement\n    #                     is not escaped.\n    # 2. (?:begin)        A non-capturing group that matches the begin\n    # 3. (.*?)            sequence. Match any char unlimited times, as few\n    #                     times as possible. Save the match in the capturing\n    #                     group after all capturing groups that can appear in\n    #                     'begin'.\n    # 4. (?<!\\\\)(?:\\\\\\\\)* Again the unescaping regex.\n    # 5. (?:end)          A non-capturing group that matches the end sequence.\n    #                     Because the 3. group is lazy (matches as few times as\n    #                     possible) the next occurring end-sequence is matched.\n    regex = (r\"(?<!\\\\)(?:\\\\\\\\)*(?:\" + begin + r\")(.*?)(?<!\\\\)((?:\\\\\\\\)*)(?:\" +\n             end + r\")\")\n\n    matches = re.finditer(regex, string, re.DOTALL)\n\n    if remove_empty_matches:\n        matches = trim_empty_matches(matches,\n                                     [compiled_begin_pattern.groups + 1,\n                                      compiled_begin_pattern.groups + 2])\n\n    matches = limit(matches, max_matches)\n\n    for elem in matches:\n        yield (elem.group(compiled_begin_pattern.groups + 1) +\n               elem.group(compiled_begin_pattern.groups + 2))\n", "path": "coalib/parsing/StringProcessing.py"}], "after_files": [{"content": "import re\n\n\ndef search_for(pattern, string, flags=0, max_match=0):\n    \"\"\"\n    Searches for a given pattern in a string.\n\n    :param pattern:   A regex pattern that defines what to match.\n    :param string:    The string to search in.\n    :param flags:     Additional flags to pass to the regex processor.\n    :param max_match: Defines the maximum number of matches to perform. If 0 or\n                      less is provided, the number of splits is not limited.\n    :return:          An iterator returning MatchObject's.\n    \"\"\"\n    for elem in limit(re.finditer(pattern, string, flags), max_match):\n        yield elem\n\n\ndef limit(iterator, count):\n    \"\"\"\n    A filter that removes all elements behind the set limit.\n\n    :param iterator: The iterator to be filtered.\n    :param count:    The iterator limit. All elements at positions bigger than\n                     this limit are trimmed off. Exclusion: 0 or numbers below\n                     does not limit at all, means the passed iterator is\n                     completely yielded.\n    \"\"\"\n    if count <= 0:  # Performance branch\n        for elem in iterator:\n            yield elem\n    else:\n        for elem in iterator:\n            yield elem\n            count -= 1\n            if count == 0:\n                break\n\n\ndef trim_empty_matches(iterator, groups=[0]):\n    \"\"\"\n    A filter that removes empty match strings. It can only operate on iterators\n    whose elements are of type MatchObject.\n\n    :param iterator: The iterator to be filtered.\n    :param groups:   An iteratable defining the groups to check for blankness.\n                     Only results are not yielded if all groups of the match\n                     are blank.\n                     You can not only pass numbers but also strings, if your\n                     MatchObject contains named groups.\n    \"\"\"\n    for elem in iterator:\n        for group in groups:\n            if len(elem.group(group)) != 0:\n                yield elem\n                continue\n\n\ndef split(pattern,\n          string,\n          max_split=0,\n          remove_empty_matches=False):\n    \"\"\"\n    Splits the given string by the specified pattern. The return character (\\n)\n    is not a natural split pattern (if you don't specify it yourself).\n    This function ignores escape sequences.\n\n    :param pattern:              A regex pattern that defines where to split.\n    :param string:               The string to split by the defined pattern.\n    :param max_split:            Defines the maximum number of splits. If 0 or\n                                 less is provided, the number of splits is not\n                                 limited.\n    :param remove_empty_matches: Defines whether empty entries should\n                                 be removed from the result.\n    :return:                     An iterator returning the split up strings.\n    \"\"\"\n    # re.split() is not usable for this function. It has a bug when using too\n    # many capturing groups \"()\".\n\n    # Regex explanation:\n    # 1. (.*?)              Match any char unlimited times, as few times as\n    #                       possible. Save the match in the first capturing\n    #                       group (match.group(1)).\n    # 2. (?:pattern)        A non-capturing group that matches the\n    #                       split-pattern. Because the first group is lazy\n    #                       (matches as few times as possible) the next\n    #                       occurring split-sequence is matched.\n    regex = r\"(.*?)(?:\" + pattern + r\")\"\n\n    item = None\n    for item in re.finditer(regex, string, re.DOTALL):\n        if not remove_empty_matches or len(item.group(1)) != 0:\n            # Return the first matching group. The pattern from parameter can't\n            # change the group order.\n            yield item.group(1)\n\n            max_split -= 1\n            if 0 == max_split:\n                break  # only reachable when max_split > 0\n\n    if item is None:\n        last_pos = 0\n    else:\n        last_pos = item.end()\n\n    # Append the rest of the string, since it's not in the result list (only\n    # matches are captured that have a leading separator).\n    if not remove_empty_matches or len(string) > last_pos:\n        yield string[last_pos:]\n\n\ndef unescaped_split(pattern,\n                    string,\n                    max_split=0,\n                    remove_empty_matches=False):\n    \"\"\"\n    Splits the given string by the specified pattern. The return character (\\n)\n    is not a natural split pattern (if you don't specify it yourself).\n    This function handles escaped split-patterns (and so splits only patterns\n    that are unescaped).\n    CAUTION: Using the escaped character '\\' in the pattern the function can\n             return strange results. The backslash can interfere with the\n             escaping regex-sequence used internally to split.\n\n    :param pattern:              A regex pattern that defines where to split.\n    :param string:               The string to split by the defined pattern.\n    :param max_split:            Defines the maximum number of splits. If 0 or\n                                 less is provided, the number of splits is not\n                                 limited.\n    :param remove_empty_matches: Defines whether empty entries should\n                                 be removed from the result.\n    :return:                     An iterator returning the split up strings.\n    \"\"\"\n    # Need to use re.search() since using splitting directly is not possible.\n    # We need to match the separator only if the number of escapes is even.\n    # The solution is to use look-behind-assertions, but these don't support a\n    # variable number of letters (means quantifiers are not usable there). So\n    # if we try to match the escape sequences too, they would be replaced,\n    # because they are consumed then by the regex. That's not wanted.\n\n    # Regex explanation:\n    # 1. (.*?)              Match any char unlimited times, as few times as\n    #                       possible. Save the match in the first capturing\n    #                       group (match.group(1)).\n    # 2. (?<!\\\\)((?:\\\\\\\\)*) Unescaping sequence. Only matches backslashes if\n    #                       their count is even.\n    # 3. (?:pattern)        A non-capturing group that matches the\n    #                       split-pattern. Because the first group is lazy\n    #                       (matches as few times as possible) the next\n    #                       occurring split-sequence is matched.\n    regex = r\"(.*?)(?<!\\\\)((?:\\\\\\\\)*)(?:\" + pattern + r\")\"\n\n    item = None\n    for item in re.finditer(regex, string, re.DOTALL):\n        concat_string = item.group(1)\n\n        if item.group(2) is not None:\n            # Escaped escapes were consumed from the second group, append them\n            # too.\n            concat_string += item.group(2)\n\n        if not remove_empty_matches or len(concat_string) != 0:\n            # Return the first matching group. The pattern from parameter can't\n            # change the group order.\n            yield concat_string\n\n            max_split -= 1\n            if max_split == 0:\n                break  # only reachable when max_split > 0\n\n    if item is None:\n        last_pos = 0\n    else:\n        last_pos = item.end()\n\n    # Append the rest of the string, since it's not in the result list (only\n    # matches are captured that have a leading separator).\n    if not remove_empty_matches or len(string) > last_pos:\n        yield string[last_pos:]\n\n\ndef search_in_between(begin,\n                      end,\n                      string,\n                      max_matches=0,\n                      remove_empty_matches=False):\n    \"\"\"\n    Searches for a string enclosed between a specified begin- and end-sequence.\n    Also enclosed \\n are put into the result. Doesn't handle escape sequences.\n\n    :param begin:                A regex pattern that defines where to start\n                                 matching.\n    :param end:                  A regex pattern that defines where to end\n                                 matching.\n    :param string:               The string where to search in.\n    :param max_matches           Defines the maximum number of matches. If 0 or\n                                 less is provided, the number of splits is not\n                                 limited.\n    :param remove_empty_matches: Defines whether empty entries should\n                                 be removed from the result.\n    :return:                     An iterator returning the matched strings.\n    \"\"\"\n\n    # Compilation of the begin sequence is needed to get the number of\n    # capturing groups in it.\n    compiled_begin_pattern = re.compile(begin)\n\n    # Regex explanation:\n    # 1. (?:begin) A non-capturing group that matches the begin sequence.\n    # 2. (.*?)     Match any char unlimited times, as few times as possible.\n    #              Save the match in the first capturing group\n    #              (match.group(1)).\n    # 3. (?:end)   A non-capturing group that matches the end sequence.\n    #              Because the previous group is lazy (matches as few times as\n    #              possible) the next occurring end-sequence is matched.\n    regex = r\"(?:\" + begin + r\")(.*?)(?:\" + end + r\")\"\n\n    matches = re.finditer(regex, string, re.DOTALL)\n\n    if remove_empty_matches:\n        matches = trim_empty_matches(matches,\n                                     [compiled_begin_pattern.groups + 1])\n\n    matches = limit(matches, max_matches)\n\n    for elem in matches:\n        yield elem.group(compiled_begin_pattern.groups + 1)\n\n\ndef unescaped_search_in_between(begin,\n                                end,\n                                string,\n                                max_matches=0,\n                                remove_empty_matches=False):\n    \"\"\"\n    Searches for a string enclosed between a specified begin- and end-sequence.\n    Also enclosed \\n are put into the result.\n    Handles escaped begin- and end-sequences (and so only patterns that are\n    unescaped).\n    CAUTION: Using the escaped character '\\' in the begin- or end-sequences\n             the function can return strange results. The backslash can\n             interfere with the escaping regex-sequence used internally to\n             match the enclosed string.\n\n    :param begin:                The begin-sequence where to start matching.\n                                 Providing regexes (and not only fixed strings)\n                                 is allowed.\n    :param end:                  The end-sequence where to end matching.\n                                 Providing regexes (and not only fixed strings)\n                                 is allowed.\n    :param string:               The string where to search in.\n    :param max_matches           Defines the maximum number of matches. If 0 or\n                                 less is provided, the number of splits is not\n                                 limited.\n    :param remove_empty_matches: Defines whether empty entries should\n                                 be removed from the result.\n    :return:                     An iterator returning the matched strings.\n    \"\"\"\n    # Compilation of the begin sequence is needed to get the number of\n    # capturing groups in it.\n    compiled_begin_pattern = re.compile(begin)\n\n    # Regex explanation:\n    # 1. (?<!\\\\)(?:\\\\\\\\)* Unescapes the following char. The first part of this\n    #                     regex is a look-behind assertion. Only match the\n    #                     following if no single backslash is before it.\n    #                     The second part matches all double backslashes.\n    #                     In fact this sequence matches all escapes that occur\n    #                     as a multiple of two, means the following statement\n    #                     is not escaped.\n    # 2. (?:begin)        A non-capturing group that matches the begin\n    # 3. (.*?)            sequence. Match any char unlimited times, as few\n    #                     times as possible. Save the match in the capturing\n    #                     group after all capturing groups that can appear in\n    #                     'begin'.\n    # 4. (?<!\\\\)(?:\\\\\\\\)* Again the unescaping regex.\n    # 5. (?:end)          A non-capturing group that matches the end sequence.\n    #                     Because the 3. group is lazy (matches as few times as\n    #                     possible) the next occurring end-sequence is matched.\n    regex = (r\"(?<!\\\\)(?:\\\\\\\\)*(?:\" + begin + r\")(.*?)(?<!\\\\)((?:\\\\\\\\)*)(?:\" +\n             end + r\")\")\n\n    matches = re.finditer(regex, string, re.DOTALL)\n\n    if remove_empty_matches:\n        matches = trim_empty_matches(matches,\n                                     [compiled_begin_pattern.groups + 1,\n                                      compiled_begin_pattern.groups + 2])\n\n    matches = limit(matches, max_matches)\n\n    for elem in matches:\n        yield (elem.group(compiled_begin_pattern.groups + 1) +\n               elem.group(compiled_begin_pattern.groups + 2))\n", "path": "coalib/parsing/StringProcessing.py"}]}