我正在使用正则表达式构建文本解析器。我需要将字符串中的所有制表符转换为空格字符。我不能假设标签应该包含多少空格,否则我可以用4个空格字符替换标签。对于这类问题有没有好的解决方案。我需要在代码中执行此操作,因此我无法使用外部工具。
不幸的是,这些答案都没有解决我遇到的问题。我从外部文本文件中提取文本,我无法假设它们是如何创建的,或者是用于创建它们的操作系统。我相信制表符的长度可能会有所不同,所以如果我在阅读文本文件时遇到标签,我想知道应该用多少空格字符替换它。
答案 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 = tab_length - (current_position % tab_length)
。答案 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个空格,一个笑脸......无论如何......所以......没有真正的答案。