给定绝对基于0的字符串索引,确定基于1的行和列号(C#)

时间:2018-06-25 02:31:41

标签: c# .net

在C#中,给定一个字符串和一个从0开始的索引值,如何确定从1开始的行号和列号?

这应该适用于来自具有不同行尾约定的各种平台的字符串。

编辑:我Azure Data Factory Cosmos DB Dataset properties可以在多种情况下使用,并且简洁明了。我对其他答案持开放态度,这些答案可以通过使用具有不同行尾和行数的示例来证明它们更快或更正确。

3 个答案:

答案 0 :(得分:0)

从您提出的问题看来,您似乎想要一个类似于文本编辑器如何显示行号和列号的功能。尝试一下这个想法,请查看下面的功能。您可以使用子字符串直到目标索引,然后在换行符\n上进行分割。行数是您的行号,因为子字符串仅包含直至目标索引的行。故意忽略拆分中的回车符(\r)可确保将它们计入索引中,并且不影响结果,从而确保跨平台兼容性。最后,最后一列的长度是行号,这也是因为子字符串在目标索引处结束。

using System;
using System.Linq;

public class Program
{
    public static void Main()
    {
        Console.WriteLine(FindIndexPair("Hello\r\nWorld", 0)); // (1, 1)
        Console.WriteLine(FindIndexPair("Hello\r\nWorld", 4)); // (1, 5)
        Console.WriteLine(FindIndexPair("Hello\r\nWorld", 7)); // (2, 1)
        Console.WriteLine(FindIndexPair("Hello\r\nWorld", 11)); // (2, 5)

        Console.WriteLine(FindIndexPair("Hello\nWorld", 0)); // (1, 1)
        Console.WriteLine(FindIndexPair("Hello\nWorld", 4)); // (1, 5)
        Console.WriteLine(FindIndexPair("Hello\nWorld", 6)); // (2, 1)
        Console.WriteLine(FindIndexPair("Hello\nWorld", 10)); // (2, 5)
    }

    public static Tuple<int, int> FindIndexPair(string val, int index)
    {
        var upToIndex = val.Substring(0, index + 1);
        var lines = upToIndex.Split('\n');
        var lineNumber = lines.Count();
        var columnNumber = lines.Last().Length;
        return Tuple.Create(lineNumber, columnNumber);
    }
}

答案 1 :(得分:0)

@tyler的代码变量支持\r\n\r\n,例如StringReader.ReadLine()

https://msdn.microsoft.com/en-us/library/system.io.stringreader.readline(v=vs.110).aspx)     公共静态(int row,int col)RowColumn(字符串str,int ix)     {         int row = 1,col = 1;

    for (int i = 0; i < ix; i++)
    {
        char ch = str[i];

        if (ch == '\r')
        {
            // Skip the optional \n
            if (i + 1 < ix && str[i + 1] == '\n')
            {
                i++;
            }

            row++;
            col = 1;
        }
        else if (ch == '\n')
        {
            row++;
            col = 1;
        }
        else
        {
            col++;
        }
    }

    return (row, col);
}

使用方式:

Console.WriteLine(RowColumn("Hello\r\nWorld", 0)); // (1, 1)
Console.WriteLine(RowColumn("Hello\r\nWorld", 4)); // (1, 5)
Console.WriteLine(RowColumn("Hello\r\nWorld", 7)); // (2, 1)
Console.WriteLine(RowColumn("Hello\r\nWorld", 11)); // (2, 5)

Console.WriteLine(RowColumn("Hello\nWorld", 0)); // (1, 1)
Console.WriteLine(RowColumn("Hello\nWorld", 4)); // (1, 5)
Console.WriteLine(RowColumn("Hello\nWorld", 6)); // (2, 1)
Console.WriteLine(RowColumn("Hello\nWorld", 10)); // (2, 5)

Console.WriteLine(RowColumn("Hello\rWorld", 0)); // (1, 1)
Console.WriteLine(RowColumn("Hello\rWorld", 4)); // (1, 5)
Console.WriteLine(RowColumn("Hello\rWorld", 6)); // (2, 1)
Console.WriteLine(RowColumn("Hello\rWorld", 10)); // (2, 5)

var rc = RowColumn("Hello\rWorld", 10);
int row = rc.row;
int col = rc.col;

答案 2 :(得分:0)

这是一种确定源字符串中换行总数的方法,使逻辑更简洁:

public (int line, int column) GetLocation(string value, int position)
{
    var line = 1;
    var column = position + 1;

    var matches = new Regex("\r\n?|\n").Matches(value);
    for (var i = 0; i < matches.Count; i++)
    {
        var match = matches[i];
        if (match.Index >= position)
        {
            break;
        }

        line += 1;
        column = position + 1 - (match.Index + match.Length);
    }

    return (line, column);
}