|
13 | 13 | "keep_attributes", |
14 | 14 | "split_ignoring_parentheses", |
15 | 15 | "RingParam", |
| 16 | + "protect", |
| 17 | + "restore", |
16 | 18 | ] |
17 | 19 |
|
18 | 20 | import collections |
|
32 | 34 | from at.lattice import idtable_element |
33 | 35 |
|
34 | 36 | _ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") |
| 37 | +_placeholder = "placeholder" |
35 | 38 |
|
36 | 39 |
|
37 | 40 | def _no_encoder(v): |
@@ -379,25 +382,41 @@ def element_to_dict(elem: Element, encoder: Callable[[Any], Any] = _no_encoder) |
379 | 382 | return dct |
380 | 383 |
|
381 | 384 |
|
382 | | -def split_ignoring_parentheses(string: str, delimiter: str = ",") -> list[str]: |
383 | | - """Split a string while keeping parenthesized expressions intact |
| 385 | +def split_ignoring_parentheses( |
| 386 | + string: str, |
| 387 | + delimiter: str = ",", |
| 388 | + fence: tuple[str, str] = ('\\(', '\\)'), |
| 389 | + maxsplit: int = -1, |
| 390 | +) -> list[str]: |
| 391 | + """Split a string while keeping protected expressions intact |
384 | 392 |
|
385 | 393 | Example: "l=0,hom(4,0.0,0)" -> ["l=0", "hom(4,0.0,0)"] |
386 | 394 | """ |
387 | | - placeholder = "placeholder" |
| 395 | + substituted, matches = protect(string, fence=fence) |
| 396 | + parts = substituted.split(delimiter, maxsplit=maxsplit) |
| 397 | + return restore(matches, *parts) |
| 398 | + |
| 399 | + |
| 400 | +def protect(string: str, fence: tuple[str, str] = ('"', '"')): |
| 401 | + inf, outf = fence |
| 402 | + pattern = f"{inf}.*?{outf}" |
388 | 403 | substituted = string[:] |
389 | | - matches = collections.deque(re.finditer("\\(.*?\\)", string)) |
| 404 | + matches = collections.deque(re.finditer(pattern, string)) |
390 | 405 | for match in matches: |
391 | | - substituted = substituted.replace(match.group(), placeholder, 1) |
392 | | - parts = substituted.split(delimiter) |
393 | | - replaced_parts = [] |
394 | | - for part in parts: |
395 | | - if placeholder in part: |
| 406 | + substituted = substituted.replace(match.group(), _placeholder, 1) |
| 407 | + return substituted, matches |
| 408 | + |
| 409 | + |
| 410 | +def restore(matches, *parts): |
| 411 | + |
| 412 | + def rep(part): |
| 413 | + while _placeholder in part: |
396 | 414 | next_match = matches.popleft() |
397 | | - part = part.replace(placeholder, next_match.group(), 1) |
398 | | - replaced_parts.append(part) |
399 | | - assert not matches |
| 415 | + part = part.replace(_placeholder, next_match.group(), 1) |
| 416 | + return part |
400 | 417 |
|
| 418 | + replaced_parts = [rep(part) for part in parts] |
| 419 | + assert not matches |
401 | 420 | return replaced_parts |
402 | 421 |
|
403 | 422 |
|
|
0 commit comments