1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import re
def quote(input_str, specials, escape='\\'):
"""Returns a quoted version of |str|, where every character in the
iterable |specials| (usually a set or a string) and the escape
character |escape| is replaced by the original character preceded by
the escape character."""
assert len(escape) == 1
# Since escape is used in replacement pattern context, so we need to
# ensure that it stays a simple literal and cannot affect the \1
# that will follow it.
if escape == '\\':
escape = '\\\\'
if len(specials) > 0:
return re.sub(r'(' + r'|'.join(specials)+r'|'+escape + r')',
escape + r'\1', input_str)
return re.sub(r'(' + escape + r')', escape + r'\1', input_str)
def unquote(input_str, specials, escape='\\'):
"""Splits the input string |input_str| where special characters in
the input |specials| are, if not quoted by |escape|, used as
delimiters to split the string. The returned value is a list of
strings of alternating non-specials and specials used to break the
string. The list will always begin with a possibly empty string of
non-specials, but may end with either specials or non-specials."""
assert len(escape) == 1
out = []
cur_out = []
cur_special = False
lit_next = False
for c in input_str:
if cur_special:
lit_next = (c == escape)
if c not in specials or lit_next:
cur_special = False
out.append(''.join(cur_out))
if not lit_next:
cur_out = [c]
else:
cur_out = []
else:
cur_out.append(c)
else:
if lit_next:
cur_out.append(c)
lit_next = False
else:
lit_next = c == escape
if c not in specials:
if not lit_next:
cur_out.append(c)
else:
out.append(''.join(cur_out))
cur_out = [c]
cur_special = True
out.append(''.join(cur_out))
return out
|