【问题标题】:python replace backslashpython替换反斜杠
【发布时间】:2013-04-03 06:20:26
【问题描述】:

我正在尝试实现一个简单的帮助类来与 java-properties 文件进行交互。摆弄多行属性我遇到了一个问题,我无法解决,也许你可以?

类中的单元测试首先将跨越两行的多行属性写入属性文件,然后重新读取它并检查是否相等。那行得通。现在,如果我使用该类向属性添加第三行,它会使用我无法解释的额外反斜杠重新读取它。

这是我的代码:

#!/usr/bin/env python3
# -*- coding=UTF-8 -*-

import codecs
import os, re
import fileinput
import unittest

class ConfigParser:
    reProp = re.compile(r'^(?P<key>[\.\w]+)=(?P<value>.*?)(?P<ext>[\\]?)$')
    rePropExt = re.compile(r'(?P<value>.*?)(?P<ext>[\\]?)$')
    files = []

    def __init__(self, pathes=[]):
       for path in pathes:
           if os.path.isfile(path):
               self.files.append(path)

    def getOptions(self):
        result = {}
        key = ''
        val = ''

        with fileinput.input(self.files, inplace=False) as fi:
            for line in fi:
                m = self.reProp.match(line.strip())
                if m:
                    key = m.group('key')
                    val = m.group('value')
                    result[key] = val
                else:
                    m = self.rePropExt.match(line.rstrip())
                    if m:
                        val = '\n'.join((val, m.group('value')))
                        result[key] = val

        fi.close()
        return result

    def setOptions(self, updates={}):
        options = self.getOptions()
        options.update(updates)

        with fileinput.input(self.files, inplace=True) as fi:
            for line in fi:
                m = self.reProp.match(line.strip())
                if m:
                    key = m.group('key')
                    nval = options[key]
                    nval = nval.replace('\n', '\\\n')
                    print('{}={}'.format(key,nval))

            fi.close()        

class test(unittest.TestCase):
    files = ['test.properties']
    props = {'test.m.a' : 'Johnson\nTanaka'}

    def setUp(self):
        for file in self.files:
            f = codecs.open(file, encoding='utf-8', mode='w')
            for key in self.props.keys():
                val = self.props[key]
                val = re.sub('\n', '\\\n', val)
                f.write(key + '=' + val)
            f.close()

    def teardown(self):
        pass

    def test_read(self):
        c = configparser(self.files) 
        for file in self.files:
            for key in self.props.keys():
                result = c.getOptions()
                self.assertEqual(result[key],self.props[key])

    def test_write(self):
        c = ConfigParser(self.files)
        changes = {}
        for key in self.props.keys():
            changes[key] = self.change_value(self.props[key])

        c.setOptions(changes)       
        result = c.getOptions()
        print('changes: ')
        print(changes)
        print('result: ')
        print(result)
        for key in changes.keys():
            self.assertEqual(result[key],changes[key],msg=key)

    def change_value(self, value):
        return 'Smith\nJohnson\nTanaka'

if __name__ == '__main__':
    unittest.main()

测试运行的输出:

C:\pyt>propertyfileparser.py
changes:
{'test.m.a': 'Smith\nJohnson\nTanaka'}
result:
{'test.m.a': 'Smith\nJohnson\\\nTanaka'}

欢迎任何提示...

【问题讨论】:

  • 您避免使用标准库的ConfigParser 的任何特殊原因?
  • ConfigParser 能很好地读取 INI 文件,但不能很好地读取 java-properties 文件。我曾考虑使用 RawConfigParser 作为基础,但不知何故它变得不同了。

标签: python regex string encoding


【解决方案1】:

由于您在写作时在换行符前添加反斜杠,因此您在阅读时也必须将其删除。取消注释将 '\n' 替换为 '\\n' 的行可以解决问题,但我希望这也意味着文件语法不正确。

这只发生在第二个换行符的情况下,因为你将值分成一个“椭圆”和一个“nval”,其中“椭圆”是第一行,“nval”是其余的,你只做在 nval 上替换。

使用正则表达式替换来替换不是正则表达式的东西也是矫枉过正的。你可以使用 val.replace('\n', '\\n') 代替。

我会以非常不同的方式做这个解析器。好吧,首先,我根本不会这样做,我会使用现有的解析器,但如果我这样做了,我会在处理行延续问题时逐行读取文件,这样我就有了列表中的每个项目恰好有一个值。然后我会使用正则表达式将每个项目解析为一个键和一个值,并将其粘贴到字典中。

您改为单独解析每一行并将续行连接到解析后的值,这在 IMO 中是完全倒退的。

【讨论】:

  • 该值不分离为椭圆和nval,但旧值(椭圆)不打印到文件中,只打印新值(nval)。 nval 在替换前包含“Smith\nJohnson\nTanaka”。
  • 即使使用 str.replace 也不能解决问题,我更新了问题中的代码。
  • @BeowulfOF:你的程序太奇怪了,我不会在没有报酬的情况下调试它,但是我之前查看的结果是只包含“Johnson\nTanaka”的字符串,它会还要解释会发生什么。显然 fileinput 将重定向 sys.stdout 并且它很难调试。如果我是你,我会停止使用它。
  • 感谢您花时间忽略我的代码。但是当你这样做的时候,做对了。没有人会强迫你做任何事情。吸引那些使用其他方法而不是你的人真的没有意义。如果你不想看代码,就不要这样做,但不要试图强迫我,像你一样编码,那太粗鲁了。
  • @BeowulfOF:我不会强迫你,就像你强迫我一样。我给你推荐,你听听就好。基本问题也已确定:在写入时将 '\n' 替换为 '\\\n',但在读取时不会。也许我误解了椭圆和 nval,但这并没有改变您将第一行与以下几行分开处理的事实,而这些 是代码的基本问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
相关资源
最近更新 更多