Converting index of character in a strign to the corresponding line and column of the character in the string

The question

Is there any module that has a convenient function that takes a string and an index of character in it and returns line number and column number of the character in the string?

Example

For example I have this string with line numbers written in front of every line in square bracets and separated by a space:

[1] Lorem ipsum dolor sit amet, consectetur

[2] sit amet hendrerit lorem auctor. Nulla in

[3] egestas diam, sed semper justo. Ut risus nulla,

[4] vulputate eget tempor in, tempor sit amet orci.

[5] Etiam sollicitudin porta odio, eu dignissim est

I want to get line number and column of 45th character. It will be 2nd line 6th character(if I counted correctly)

Why I need this

I’m parsing a string and I want to raise exception when I can’t parse something. In a more CS way: I want to parse a string containing code in certain language and if something in the code violates the rules of the language I want to raise an exception about it. And I want to include a line number and column number of character in the exception message, but I only have index of the character.

Answer

This seems to be a simple application of the standard Python library. It’s possible that the library doesn’t quite have an interface which is convenient enough, but it’s easy enough to write:

def line_col(str, idx):
    """Returns a 2-tuple which translates string index 'idx' into
       line and column counts. 'idx' is a normal Python 0-based index;
       line and column are 1-based. So line_col(str, 0) will return (1, 1).
       The newline character is considered to be the last character of a
       line.
       The function does not check whether 'idx' is in range; if idx greater
       than or equal to the length of 'str', the result will be as though
       'str' had (idx + 1 - len(str)) extra characters (none of which are
       newlines) appended to the end
    """
    return str.count('n', 0, idx) + 1, idx - str.rfind('n', 0, idx)