C# 用对象替换字符串的部分
我试图将字符串的一部分转换成不同的对象,并将它们连接到一个列表或数组中,这无关紧要。 下面是一个例子: 示例字符串“这是一个测试字符串。\n\t这是一个带制表符的新行” 我想得到一个输出,如下所示:C# 用对象替换字符串的部分,c#,string,split,C#,String,Split,我试图将字符串的一部分转换成不同的对象,并将它们连接到一个列表或数组中,这无关紧要。 下面是一个例子: 示例字符串“这是一个测试字符串。\n\t这是一个带制表符的新行” 我想得到一个输出,如下所示: new List<OpenXmlElement>(){ new Text("This is a test string."), new Break(),//this is for the \n char
new List<OpenXmlElement>(){
new Text("This is a test string."),
new Break(),//this is for the \n char
new TabChar(), //this is for the \t char
new Text("This is a new line with a tab")
};
新列表(){
新文本(“这是一个测试字符串。”),
new Break(),//这是用于\n字符的
new TabChar(),//这是用于\t字符的
新文本(“这是带选项卡的新行”)
};
我已经在字典中有了一些字符和类类型,我计划使用反射来实例化它们
public static Dictionary<string, Type> Tags = new Dictionary<string, Type>()
{
{"\n", typeof(Break)},
{"\t", typeof(TabChar)}
};
publicstaticdictionary标记=newdictionary()
{
{“\n”,typeof(Break)},
{“\t”,typeof(TabChar)}
};
我想我可以使用子字符串或正则表达式,但我希望找到一个更干净的解决方案
如果问题不够清楚,很抱歉。我很乐意回答你的任何问题
这是我的全班
public class FormatConverter:IFormatConverter
{
public static Dictionary<string, Type> Tags = new Dictionary<string, Type>()
{
{"\n", typeof(Break)},
{"\t", typeof(TabChar)}
};
public IEnumerable<OpenXmlElement> Convert(string format)
{
foreach (KeyValuePair<string,Type> pair in Tags)
{
var items = format.Split(
new []{pair.Key},StringSplitOptions.RemoveEmptyEntries
);
foreach (var item in items)
{
yield return new Text(item);
yield return Activator.CreateInstance(pair.Value) as OpenXmlElement;
}
format = format.Replace(pair.Key,"");
}
}
}
公共类FormatConverter:IFormatConverter
{
公共静态字典标记=新字典()
{
{“\n”,typeof(Break)},
{“\t”,typeof(TabChar)}
};
公共IEnumerable转换(字符串格式)
{
foreach(标记中的KeyValuePair对)
{
var items=format.Split(
新建[]{pair.Key},StringSplitOptions.RemoveEmptyEntries
);
foreach(项目中的var项目)
{
返回新文本(项目);
将Activator.CreateInstance(pair.Value)作为OpenXmlElement返回;
}
format=format.Replace(pair.Key,“”);
}
}
}
我知道它有什么问题,只是不知道如何修复。您可以使用Split()方法两次。第一次在“\n”上拆分,然后可以在结果上循环,在每个项目之间插入打断对象
然后在“\t”的所有子字符串上运行拆分,并再次循环在项目之间插入选项卡对象
这不是最有效的,因为您要循环多次,但是递归应该使代码非常简单
IEnumerable<OpenXmlElement> Convert(string testString) {
IEnumerable<OpenXmlElement> tabOutput = ConvertString<TabChar>(testString, '\t');
List<OpenXmlElement> finalOutput = new List<OpenXmlElement>();
foreach(OpenXmlElement oxe in tabOutput){
if (oxe is Text)
{
IEnumerable<OpenXmlElement> breakOutput = ConvertString<Break>(((Text)oxe).WrappedText, '\n');
finalOutput.AddRange(breakOutput);
}
else
{
finalOutput.Add(oxe);
}
}
}
IEnumerable<OpenXmlElement> ConvertString<T>(string input, char pattern)
where T: OpenXmlElement, new() {
List<OpenXmlElement> output = new List<OpenXmlElement>();
string[] parts = input.Split( pattern);
if (parts.Length > 1)
{
for (int i = 0; i < parts.Length; i++)
{
string part = parts[i];
if (!string.IsNullOrEmpty(part))
{
output.Add(new Text(part));
}
if (i < (parts.Length - 1))
{
output.Add(new T());
}
}
}
else
{
output.Add(new Text(input));
}
return output;
}
IEnumerable转换(字符串测试字符串){
IEnumerable tabOutput=ConvertString(testString,'\t');
List finalOutput=新列表();
foreach(tabOutput中的openxmlementoxe){
if(oxe是文本)
{
IEnumerable breakOutput=ConvertString(((Text)oxe).WrappedText,'\n');
最终输出。添加范围(断开输出);
}
其他的
{
最终输出。添加(牛);
}
}
}
IEnumerable ConvertString(字符串输入,字符模式)
其中T:openxmlement,new(){
列表输出=新列表();
string[]parts=input.Split(模式);
如果(零件长度>1)
{
对于(int i=0;i
您的另一个选择是自己手动遍历字符串,并在运行时生成结果。它可能看起来不太优雅,但你可以一次就做到
List<OpenXmlElement> output = new List<OpenXmlElement>();
string testString = "This is a test string.\n \t This is a new line with a tab";
System.Text.StringBuilder currentLine = new System.Text.StringBuilder();
for (int i = 0; i < testString.Length; i++) {
char curChar = testString[i];
bool clearCurrLine = true;
OpenXmlElement objToAdd = null;
switch (curChar)
{
case '\n':
objToAdd = new Break();
break;
case '\t':
objToAdd = new TabChar();
break;
default:
currentLine.Append(curChar);
clearCurrLine = false;
break;
}
if (clearCurrLine)
{
output.Add(new Text(currentLine.ToString()));
currentLine.Clear();
output.Add(objToAdd);
}
}
if (currentLine.Length > 0)
{
output.Add(new Text(currentLine.ToString()));
}
列表输出=新列表();
string testString=“这是一个测试字符串。\n\t这是一个带制表符的新行”;
System.Text.StringBuilder currentLine=新的System.Text.StringBuilder();
for(int i=0;i0)
{
添加(新文本(currentLine.ToString());
}
这里有一个解析示例文本的解决方案。在实际情况下,它可能不太管用:
private readonly static Dictionary<char, Type> Tokens = new Dictionary<char, Type> {
{ '\n', typeof(Break) },
{ '\t', typeof(TabChar) }
};
private static IEnumerable<OpenXmlElement> Tokenize(string text)
{
var start = 0;
var pos = 0;
foreach (var c in text)
{
Type tokenType;
if (Tokens.TryGetValue(c, out tokenType))
{
if (pos > 0)
{
yield return new Text(text.Substring(start, pos));
}
yield return (OpenXmlElement)Activator.CreateInstance(tokenType);
start += pos + 1;
pos = 0;
}
else
{
pos++;
}
}
if (pos > 0)
{
yield return new Text(text.Substring(start));
}
}
static void Main(string[] args)
{
var tokens = Tokenize("This is a test string.\n \t This is a new line with a tab").ToArray();
}
private readonly static Dictionary Tokens=new Dictionary{
{'\n',typeof(Break)},
{'\t',typeof(TabChar)}
};
私有静态IEnumerable标记化(字符串文本)
{
var start=0;
var-pos=0;
foreach(文本中的var c)
{
类型标记类型;
if(Tokens.TryGetValue(c,out tokenType))
{
如果(位置>0)
{
返回新文本(Text.Substring(start,pos));
}
收益返回(OpenXmlElement)Activator.CreateInstance(tokenType);
开始+=位置+1;
pos=0;
}
其他的
{
pos++;
}
}
如果(位置>0)
{
返回新文本(Text.Substring(start));
}
}
静态void Main(字符串[]参数)
{
var tokens=Tokenize(“这是一个测试字符串。\n\t这是一个带制表符的新行”).ToArray();
}
我已编辑了您的标题。请看“,”其中的共识是“不,他们不应该”。对不起,我不理解这个问题。在代码的哪一部分需要帮助?实例化Break和TabChar对象?至于带有的字典,我看不出有任何问题,你不能用字符串值访问它并获取类型吗?我知道如何实例化它们,但我不知道如何解析字符串以获得正确顺序的项。字典就在那里,只是为了显示我从哪里得到的数据。ThanksIt听起来像是要对文本执行词法分析()。在执行第二次拆分时,需要解析第一次拆分的各个片段。您正在拆分原始文本(减去