Python Regex Raw:如何匹配连续行中每一行的新行?

时间:2014-10-31 21:28:44

标签: python regex

我有以下文字:

s = """
{
    "list-of-stuff": "{
        (analog-input, 1), (analog-input, 2), (analog-input, 3),
        (analog-input, 4), (analog-input, 5), (analog-input, 6),
        (analog-input, 7), (analog-input, 8), (analog-input, 9),
        (analog-input, 10), (analog-input, 11), (analog-input, 12),
        (analog-input, 13), (analog-input, 14), (analog-input, 15),
        (analog-input, 16), (analog-input, 17), (analog-input, 18),
        (analog-input, 19), (analog-input, 20), (analog-input, 21),
        (analog-input, 22), (analog-input, 23), (analog-input, 24),
        (analog-input, 25), (analog-input, 26), (analog-input, 27),
        (analog-input, 28), (analog-input, 29), (analog-input, 30),
        (analog-input, 31), (analog-input, 32), (analog-output, 1)
    }"
},
{
    "identifier": "(analog-input, 0)",
    "name": "AI 00",
    "type": "analog-input",
    "value": "?",
    "description": "Temp",
    "flags": "{false,false,false}",
    "state": "normal",
    "service": "FALSE",
    "reliability": "?"
}
"""

我想将第二个字符串({...})中的所有换行符从\n转换为\\n。 (我试图让这个JSON可读)我该怎么做?

以下是我的尝试:

s = re.sub(r'^[^"}]+,(\s*)\n', r'\1,\2\\n', s, flags=re.MULTILINE)
s = re.sub(r'^[^"}]+,(\s*)$', r'\1,\2\\n', s, flags=re.MULTILINE)

不幸的是,两者都无效。我得到的最接近产生以下输出:

s = """
{
    "list-of-stuff": "{
        (analog-input, 1), (analog-input, 2), (analog-input, 3),
        (analog-input, 4), (analog-input, 5), (analog-input, 6),
        (analog-input, 7), (analog-input, 8), (analog-input, 9),
        (analog-input, 10), (analog-input, 11), (analog-input, 12),
        (analog-input, 13), (analog-input, 14), (analog-input, 15),
        (analog-input, 16), (analog-input, 17), (analog-input, 18),
        (analog-input, 19), (analog-input, 20), (analog-input, 21),
        (analog-input, 22), (analog-input, 23), (analog-input, 24),
        (analog-input, 25), (analog-input, 26), (analog-input, 27),
        (analog-input, 28), (analog-input, 29), (analog-input, 30),\n        (analog-input, 31), (analog-input, 32), (analog-output, 1)
    }"
},
{
    "identifier": "(analog-input, 0)",
    "name": "AI 00",
    "type": "analog-input",
    "value": "?",
    "description": "Temp",
    "flags": "{false,false,false}",
    "state": "normal",
    "service": "FALSE",
    "reliability": "?"
}
"""

似乎re.MULTILINE模式在所有连续行上进行一次匹配。但是,我需要匹配EACH线。不幸的是,我需要re.MULTILINE,否则\n无法匹配。有什么建议?

更新

我更新了我的问题以更好地反映我的情况。该字符串具有我需要满足的其他属性,这在我的正则表达式中显示。例如,我需要从匹配项中排除},,以及不在JSON字符串中的其他行。因此,我不能简单地用\n替换所有\\n

很抱歉这个混乱。

4 个答案:

答案 0 :(得分:3)

ErlVolton解决方案符合您的最佳选择。但是,如果你仍然想使用字符串操作或正则表达式来执行此操作。你可以这样做:

s = s.replace('\n','\\n')

答案 1 :(得分:3)

MULTILINE的事情并不是解决这个问题的正确方法。使用更简单的解决方案,这是一个更简单的问题。

在正则表达式中,默认情况下重复是贪婪的。所以[^"}]+将匹配尽可能多的字符,同时仍然使模式的其余部分匹配。输入中的 last \n最终与您模式中的\n匹配,其中\n s匹配作为[^"}]+的一部分。

但是你可以使用+?代替+使其变得非贪婪,在这种情况下,它会匹配为少数字符,同时仍然可以其余的模式匹配。因此输入中的第一个 \n最终匹配模式中的一个,因此每一行都是一个单独的匹配。

^[^"}]+?,(\s*)$

Regular expression visualization

Debuggex Demo

答案 2 :(得分:1)

幸运的是,不需要regex-fu来逃避某些东西,因此它是有效的JSON。 json module会为您完成,特别是json.dumps()。我不打算使用你的示例文本,因为它不是有效的python,你有一个多行字符串没有三引号而没有延续。

>>> import json
>>> x = "foo\nbar"
>>> json.dumps(x)
'"foo\\nbar"'

要回答您的字面问题,我认为re.sub("\n","\\\\n", your_text)可以正常工作:

>>> import re
>>> y = "foo\nbar\njaz"
>>> re.sub("\n","\\\\n",y)
'foo\\nbar\\njaz'

答案 3 :(得分:0)

你需要使用这样的多行字符串:

s= '''
"list-of-stuff": "{ 
(analog-input, 1), (analog-input, 2), (analog-input, 3), 
(analog-input, 4), (analog-input, 5), (analog-input, 6), 
(analog-input, 7), (analog-input, 8), (analog-input, 9), 
(analog-input, 10), (analog-input, 11), (analog-input, 12), 
(analog-input, 13), (analog-input, 14), (analog-input, 15), 
(analog-input, 16), (analog-input, 17), (analog-input, 18), 
(analog-input, 19), (analog-input, 20), (analog-input, 21), 
(analog-input, 22), (analog-input, 23), (analog-input, 24), 
(analog-input, 25), (analog-input, 26), (analog-input, 27), 
(analog-input, 28), (analog-input, 29), (analog-input, 30), 
(analog-input, 31), (analog-input, 32), (analog-output, 1)
}"'''

s.replace('\n','\\n')

现在替换将起作用