将制表符转换为.NET字符串中的空格

时间:2009-02-03 17:21:23

标签: .net string

我正在使用正则表达式构建文本解析器。我需要将字符串中的所有制表符转换为空格字符。我不能假设标签应该包含多少空格,否则我可以用4个空格字符替换标签。对于这类问题有没有好的解决方案。我需要在代码中执行此操作,因此我无法使用外部工具。


不幸的是,这些答案都没有解决我遇到的问题。我从外部文本文件中提取文本,我无法假设它们是如何创建的,或者是用于创建它们的操作系统。我相信制表符的长度可能会有所不同,所以如果我在阅读文本文件时遇到标签,我想知道应该用多少空格字符替换它。

11 个答案:

答案 0 :(得分:16)

不幸的是,你需要假设一个标签代表多少个空格。您应该将其设置为固定值(如上面提到的四个)或将其设置为用户选项。

最快的方法是.NET(我正在使用C#):

var NewString = "This is a string with a    Tab";
var TabLength = 4;
var TabSpace = new String(' ', TabLength);

NewString = NewString.Replace("\t", TabSpace);

然后,您可以将TabLength变量更改为您想要的任何内容,通常如前所述,四个空格字符。

所有操作系统中的标签长度​​相同,一个标签!不同的是软件显示它们的方式,通常这是四个空格字符的等效宽度,这也假设显示使用固定宽度字体,如Courier New

例如,我的IDE of choice允许我将制表符的宽度更改为适合我的值。

答案 1 :(得分:6)

我不确定标签是如何从Unix文本文件中读取的,或者您的各种格式是什么,但这适用于内联文本。也许它会有所帮助。

var textWithTabs = "some\tvalues\tseperated\twith\ttabs";
var textWithSpaces = string.Empty;

var textValues = textWithTabs.Split('\t');

foreach (var val in textValues)
{
    textWithSpaces += val + new string(' ', 8 - val.Length % 8);
}

Console.WriteLine(textWithTabs);
Console.WriteLine(textWithSpaces);
Console.Read();

答案 2 :(得分:3)

我认为你的意思是说你想用它们扩展到的有效空间来替换制表符。想到的第一种方式不涉及正则表达式(我不知道这个问题可以通过它们来解决)。

  • 逐个字符串逐字逐句,跟踪字符串中的当前位置。
  • 找到标签后,请将其替换为N个空格,其中N = tab_length - (current_position % tab_length)
  • 将N添加到当前位置并继续使用字符串。

答案 3 :(得分:3)

(如果您正在寻找如何将标签转换为编辑器中的空格,请参阅我的答案末尾)

差不多8年的问题,但我最近要求用空格替换制表符。

该解决方案将标签替换为最多 4或8个空格。

逻辑迭代输入字符串,一次一个字符并跟踪输出字符串中的当前位置(列#)。

  • 如果遇到\t(tab char) - 查找下一个制表位,计算到下一个制表位需要多少空格,用这些空格数替换\ t。
  • 如果\n(新行) - 将其追加到输出字符串并将位置指针重置为新行上的1。 Windows上的新行是\r\n,而UNIX(或者各种)使用\n,所以我认为这应该适用于两个平台。我已在Windows上测试过,但没有方便的UNIX。
  • 任何其他字符 - 将其附加到输出字符串并递增位置。

using System.Text;

namespace CSharpScratchPad
{
    class TabToSpaceConvertor
    {
        static int GetNearestTabStop(int currentPosition, int tabLength)
        {
            // if already at the tab stop, jump to the next tab stop.
            if ((currentPosition % tabLength) == 1)
                currentPosition += tabLength;
            else
            {
                // if in the middle of two tab stops, move forward to the nearest.
                for (int i = 0; i < tabLength; i++, currentPosition++)
                    if ((currentPosition % tabLength) == 1)
                        break;
            }

            return currentPosition;
        }

        public static string Process(string input, int tabLength)
        {
            if (string.IsNullOrEmpty(input))
                return input;

            StringBuilder output = new StringBuilder();

            int positionInOutput = 1;
            foreach (var c in input)
            {
                switch (c)
                {
                    case '\t':
                        int spacesToAdd = GetNearestTabStop(positionInOutput, tabLength) - positionInOutput;
                        output.Append(new string(' ', spacesToAdd));
                        positionInOutput += spacesToAdd;
                        break;

                    case '\n': 
                        output.Append(c);
                        positionInOutput = 1;
                        break;

                    default:
                        output.Append(c);
                        positionInOutput++;
                        break;
                }
            }
            return output.ToString();
        }
    }
}

调用代码就像

string input = "I\tlove\tYosemite\tNational\tPark\t\t,\t\t\tGrand Canyon,\n\t\tand\tZion";
string output = CSharpScratchPad.TabToSpaceConvertor.Process(input, 4);

输出字符串将获得值

I   love    Yosemite    National    Park        ,           Grand Canyon,
        and Zion

如何将标签转换为编辑器中的空格?

如果您偶然发现了这个问题,因为您找不到将标签转换为编辑器中空格的选项(就像我一样,并考虑编写自己的实用程序),这里的选项位于不同的编辑器中 -

Notepad++:              Edit > Blank Operations > TAB to Space
Visual Studio:          Edit > Advanced > Untabify Selected Lines
SQL Management Studio:  Edit > Advanced > Untabify Selected Lines

答案 4 :(得分:1)

这正是他们所说的需要。我在Visual Basic 6.0写回来了。我做了一些快速的VB.NET 2010更新,但它可以使用一些更好的修复它。只需确保并设置所需的标签宽度;它在那里设置为8。只需将字符串发送给它,或者甚至将其固定在文本框中,如下所示:

RichTextBox1.Text = strFixTab(RichTextBox1.Text)

Function strFixTab(ByVal TheStr As String) As String
    Dim c As Integer
    Dim i As Integer
    Dim T As Integer
    Dim RetStr As String
    Dim ch As String
    Dim TabWidth as Integer = 8    ' Set the desired tab width

    c = 1
    For i = 1 To TheStr.Length
        ch = Mid(TheStr, i, 1)
        If ch = vbTab Then
            T = (TabWidth + 1) - (c Mod TabWidth)
            If T = TabWidth + 1 Then T = 1
            RetStr &= Space(T)
            c += T - 1
        Else
            RetStr &= ch
        End If
        If ch = vbCr Or ch = vbLf Then
            c = 1
        Else
            c += 1
        End If
    Next
    Return RetStr
End Function

答案 5 :(得分:0)

您可以使用替换功能:

char tabs = '\u0009';
String newLine = withTabs.Replace(tabs.ToString(), "    ");

答案 6 :(得分:0)

我不确定我的解决方案在执行方面是否更有效但在代码中更紧凑。这与@ckal的解决方案很接近,但是使用Join函数而不是'+ ='重新组合拆分字符串。

public static string ExpandTabs(string input, int tabLength)
{
    string[] parts = input.Split('\t');
    int count = 0;
    int maxpart = parts.Count() - 1;
    foreach (string part in parts)
    {
        if (count < maxpart)
            parts[count] = part + new string(' ', tabLength - (part.Length % tabLength));
        count++;
    }
    return(string.Join("", parts));
}

答案 7 :(得分:-1)

您希望能够将标签转换为N个空格吗?一个快速而肮脏的选择是:

output = input.Replace("\t", "".PadRight(N, (char)" "));

显然,必须在某处定义N,无论是用户输入还是程序中的其他位置。

答案 8 :(得分:-1)

Regex.Replace(input,"\t","    ");

答案 9 :(得分:-1)

我不太确定你的意思是“我不能假设一个标签应包含多少空格”,但是这个例子将用您指定的任意数量的空格替换标签。

public static string ReplaceTabs(string value, int numSpaces)
{
   string spaces = new String(' ', numSpaces);
   return value.Replace("\t", spaces);     
}

答案 10 :(得分:-1)

我认为每个人都已经覆盖了它,但是一个标签字符就是这样。一个字符..字符由\ t表示..每个应用程序可以选择显示一个空格,两个空格,4个空格,一个笑脸......无论如何......所以......没有真正的答案。