【问题标题】:Python: Get the line and column number of string index?Python:获取字符串索引的行号和列号?
【发布时间】:2014-06-30 17:32:38
【问题描述】:

假设我有一个正在操作的文本文件。像这样的东西(希望这不是太难以理解):

data_raw = open('my_data_file.dat').read()
matches = re.findall(my_regex, data_raw, re.MULTILINE)
for match in matches:
    try:
        parse(data_raw, from_=match.start(), to=match.end())
    except Exception:
        print("Error parsing data starting on line {}".format(what_do_i_put_here))
        raise

注意异常处理程序中有一个名为what_do_i_put_here 的变量。我的问题是:如何分配给该名称,以便我的脚本将打印包含我正在尝试使用的“坏区域”开头的 行号?我不介意重新阅读文件,我只是不知道我会做什么......

【问题讨论】:

  • 你的正则表达式是否消耗新行?如果没有,你可以逐行查找,然后很容易得到行号。
  • 是的,它消耗多行(这就是我使用re.MULTILINE的原因)
  • Re.findall 不返回字符串列表吗?:docs.python.org/2/library/re.html。字符串没有开始或结束方法。
  • 不,它返回一个列表MatchObject 实例,请参阅:docs.python.org/2/library/re.html#re.MatchObject

标签: python file text


【解决方案1】:

这里有一些更简洁的东西,在我看来比你自己的答案更容易理解:

def index_to_coordinates(s, index):
    """Returns (line_number, col) of `index` in `s`."""
    if not len(s):
        return 1, 1
    sp = s[:index+1].splitlines(keepends=True)
    return len(sp), len(sp[-1])

它的工作方式与您自己的答案基本相同,但通过使用字符串切片 splitlines() 实际上可以计算您需要的所有信息,而无需任何后期处理。

必须使用keepends=True 才能为行尾字符提供正确的列计数。

唯一的额外问题是空字符串的边缘情况,可以通过保护子句轻松处理。

我在 Python 3.8 中对其进行了测试,但它可能在大约 3.4 版之后正常工作(在某些旧版本中,len() 计算代码单元而不是代码点,我认为它会因包含 BMP 之外的字符的任何字符串而中断)

【讨论】:

    【解决方案2】:

    这是我写的。它未经测试且效率低下,但确实有助于使我的异常消息更加清晰:

    def coords_of_str_index(string, index):
        """Get (line_number, col) of `index` in `string`."""
        lines = string.splitlines(True)
        curr_pos = 0
        for linenum, line in enumerate(lines):
            if curr_pos + len(line) > index:
                return linenum + 1, index-curr_pos
            curr_pos += len(line)
    

    我什至没有测试过列号是否准确。我没有遵守 YAGNI

    【讨论】:

    • 我建议使用s 以避免遮蔽标准库string 模块。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    相关资源
    最近更新 更多