我想逐行处理字符串,但我想启用多行支持。这是示例文本:
First line
Second line
{{{
these three lines
I want to process
together
}}}
Last Line
我希望多行从{{{
开始,然后在}}}
结束
我曾经以下列方式逐行处理它:
lines = [l for l in text.splitlines()]
print lines
现在这段代码输出:
['First line', 'Second line', '{{{', 'these three lines', 'I want to process', 'together', '}}}', 'Last Line']
我想以某种方式让lines
包含以下内容:
['First line', 'Second line', 'these three lines I want to process together', 'Last Line']
或者,更高级的例子
First Line
Second line
Third{{{line
fourth line
fifth}}}line
sixth line
在这种情况下,我希望行包含
['First Line', 'Second line', 'Third', 'line fourth line fifth', 'line', 'sixth line']
答案 0 :(得分:3)
这是一个生成器,它将输入文件对象作为参数,并一次生成一行。它应该在同一行上接受尽可能多的{{{
和}}}
,但不会测试不平衡的构造:
def merge_lines(fd):
concat = False
for line in fd:
while True:
#print (line)
if len(line.strip()) == 0: break
if not concat:
if ('{{{' in line):
deb, line = line.split('{{{', 1)
yield deb
concat = True
old = None
else:
yield line.strip('\r\n')
line = ""
if concat:
if ('}}}' in line):
deb, line = line.split('}}}', 1)
concat = False
if old:
yield old.strip() + ' ' + deb
else: yield deb
else:
if old:
old += ' ' + line.strip('\r\n')
else:
old = line.strip('\r\n')
line = ""
Python 3中的示例:
>>> t = """First line
a{{{b}}}c{{{d
e
f}}}g{{{h
i}}}
j
k
"""
>>> for line in merge_lines(io.StringIO(t)): print(line)
First line
a
b
c
d e f
g
h i
j
k
答案 1 :(得分:2)
使用正则表达式似乎是一个明智的解决方案 - 它为您提供了两个输入选项之间的灵活性
import re
only_line = '''First line
Second line
{{{
these three lines
I want to process
together
}}}
Last Line'''
mixed_line = '''First Line
Second line
Third{{{line
fourth line
fifth}}}line
sixth line'''
def curly_brackets(input_string):
# regex - we want to match text before the backets, text in the brackets, and text after the brackets as three groups
separate = list(re.findall('(.*)\{{3}(.*)\}{3}(.*)', input_string, re.DOTALL)[0])
# 1-indexed item will be the value between brackets - replace carriage returns with spaces
separate[1] = separate[1].replace('\n', ' ')
# split according to new lines - there will be none in our bracketed section
separate = [x.strip().split('\n') for x in separate]
# flatten the lists down - each element of separate is currently a list
return [x for sublist in separate for x in sublist]
print curly_brackets(only_line)
print curly_brackets(mixed_line)
返回:
['First line', 'Second line', 'these three lines I want to process together', 'Last Line']
['First Line', 'Second line', 'Third', 'line fourth line fifth', 'line', 'sixth line']
如果您有多组花括号,但是可以适应以迭代方式应用,那么这不会起作用。
答案 2 :(得分:0)
def split(text):
lines = []
while '{{{' in text:
head, sep, tail = text.partition('{{{')
lines.extend(head.splitlines())
head, sep, tail = tail.partition('}}}')
lines.append(head.replace('\n', ' ').strip())
text = tail
lines.extend(text.splitlines())
return lines
答案 3 :(得分:0)
这是我的解决方案。这很长很简单。我希望也许有一种方法可以在几行内完成它但是当}}}
和{{{
在同一行时它不会处理案例
def _split_with_merging(text):
lines = [l for l in text.splitlines() if l != ""]
nlines = []
multiline = False
for l in lines:
if multiline:
if "}}}" in l:
lparts = l.split("}}}")
nlines[len(nlines) - 1] += lparts[0]
if lparts[1] != "":
nlines.append(lparts[1])
multiline = False
else:
nlines[len(nlines) - 1] += l
else:
if "{{{" in l:
lparts = l.split("{{{")
nlines.append(lparts[0])
if lparts[1] != "":
nlines.append(lparts[1])
multiline = True
else:
nlines.append(l)
return nlines
答案 4 :(得分:0)
您可以使用正则表达式,假设您对 Console.Write(SpinnerAnimationFrames[currentAnimationFrame]);
currentAnimationFrame++;
if(currentAnimationFrame == SpinnerAnimationFrames.Length)
{
currentAnimationFrame = 0;
}
Console.SetCursorPosition(originalX, originalY);
return currentAnimationFrame!=0?true:false;
}
{{{ }}}}
OR
text = """First line
Second line
THIS{{{
these three lines
I want to process
together
}}}
Last Line"""
import re
match_obj = re.search('{{{(.*)}}}', text, re.DOTALL)
print match_obj.group(1)
OR
r = re.compile('{{{(.*)}}}', flags=re.DOTALL)
print re.split(r, text)
# replace \n
split_list = re.split(r, text)
split_list = [l.replace('\n', '') for l in split_list]
print split_list
如果在给定文本中多次出现match_list = re.findall('{{{(.*)}}}', text, re.DOTALL)
match_list = [l.replace('\n', '') for l in match_list]
print match_list
,请通过添加“?”来使用非贪婪匹配例如{{{ }}}
答案 5 :(得分:0)
我认为这可以作为您想要实现的目标的快速而简单的解决方案:
@ElementList(entry= "PaymentTotals", inline = true, required = false)
protected List<PaymentTotalsType> paymentTotals;
可能不是最干净的代码,我认为我们应该用text = """First line
Second line
{{{
these three lines
I want to process
together
}}}
Last Line"""
all_lines = [l for l in text.splitlines()]
final_list = []
nested = False
for line in all_lines:
if line == "{{{":
nested = True
multiline = ""
continue
elif line == "}}}":
nested = False
final_list.append(multiline)
continue
if nested == True:
multiline = multiline + " " + line
else:
final_list.append(line)
print(final_list)
替换multiline = multiline + " " + line
,但我希望你能得到这个想法。
答案 6 :(得分:0)
在带有{{{
标记的循环中跟踪开始}}}
并关闭in_multi
直截了当:
def split_multi(s):
lines = []
in_multi = False
for line in s.splitlines():
if in_multi:
if '}}}' in line:
in_multi = False
split = line.split('}}}')
if split[0]:
tmp.append(split[0])
lines.append(' '.join(tmp))
if split[-1]:
lines.append(split[-1])
else:
tmp.append(line)
else:
if '{{{' in line:
split = line.split('{{{')
in_multi = True
if split[0]:
lines.append(split[0])
if split[-1]:
tmp = [split[-1]]
else:
tmp = []
else:
lines.append(line)
return lines
s1 = """First line
Second line
{{{
these three lines
I want to process
together
}}}
Last Line"""
s2 = """First Line
Second line
Third{{{line
fourth line
fifth}}}line
sixth line"""
print(split_multi(s1))
print(split_multi(s2))
#['First Line', 'Second line', 'Third', 'line fourth line fifth', 'line', 'sixth line']
输出:
['First line', 'Second line', 'these three lines I want to process together', 'Last Line']
['First Line', 'Second line', 'Third', 'line fourth line fifth', 'line', 'sixth line']
答案 7 :(得分:0)
我的2美分(使用joint
):
// assuming that program is your compiled shader program and
// gl is your WebGL context.
const cos = Math.cos;
const sin = Math.sin;
gl.uniformMatrix4fv(gl.getUniformLocation(program, 'camMatrix'), [
cos(rY) * cos(rZ), cos(rZ) * sin(rX) * sin(rY) - cos(rX) * sin(rZ), sin(rX) * sin(rZ) + cos(rX) * cos(rZ) * sin(rY), 0,
cos(rY) * sin(rZ), cos(rX) * cos(rZ) + sin(rX) * sin(rY) * sin(rZ), cos(rX) * sin(rY) * sin(rZ) - cos(rZ) * sin(rX), 0,
-sin(rY), cos(rY) * sin(rX), cos(rX) * cos(rY), 0,
0, 0, 0, 1
]);
返回:
ex1 = """First line
Second line
{{{
these three lines
I want to process
together
}}}
Last Line"""
ex2 = """First Line
Second line
Third{{{line
fourth line
fifth}}}line
sixth line"""
def parse_lines(txt, start_sep='{{{', end_sep='}}}'):
depth = 0 # 1+ if we are inside a {{{ group
# can be used to test unbalanced constructs
lines = []
current_line = ''
n = len(txt)
i = 0
while i < n:
c = txt[i]
not_handled = True
need_to_add = False
if c == '\n': # end of line
if depth == 0 : # save line and empty buffer
need_to_add = True
elif current_line != '': # add a space instead of the line break
current_line = ''.join((current_line,' '))
not_handled = False
i += 1
elif c == start_sep[0] and\
txt[i:i+len(start_sep)] == start_sep:
# ^ takes small advantage of lazy evaluation
# (see questions/13960657)
depth += 1
need_to_add = True
not_handled = False
i += len(start_sep)
elif c == end_sep[0] and\
txt[i:i+len(end_sep)] == end_sep:
depth -= 1
need_to_add = True
not_handled = False
i += len(end_sep)
if not_handled:
current_line = ''.join((current_line,c))
i += 1
elif need_to_add and current_line != '':
lines.append(current_line)
current_line = ''
if current_line != '': # add last line
lines.append(current_line)
return lines
请注意第一个示例中以>>> parse_lines(ex1)
['First line', 'Second line', 'these three lines I want to process together ', 'Last Line']
>>> parse_lines(ex2)
['First Line', 'Second line', 'Third', 'line fourth line fifth', 'line', 'sixth line']
结尾的多线上的额外' '
。