C# 使用LINQ替换特定位置的特定子字符串

C# 使用LINQ替换特定位置的特定子字符串,c#,string,linq,replace,C#,String,Linq,Replace,我有一个缩写和位置列表,我想替换特定的缩写而不是所有的缩写 public class Abbreviation { public int Pos { get; set; } public string ShortName { get; set; } public string LongName { get; set; } } class Program { static void Main(string[] args) { List<

我有一个缩写和位置列表,我想替换特定的缩写而不是所有的缩写

public class Abbreviation
{
    public int Pos { get; set; }
    public string ShortName { get; set; }
    public string LongName { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        List<Abbreviation> abbreviations = new List<Abbreviation>();
        abbreviations.Add(new Abbreviation() { Pos = 28, ShortName = "exp.", LongName = "expression" });
        abbreviations.Add(new Abbreviation() { Pos = 38, ShortName = "para.", LongName = "paragraph" });
        abbreviations.Add(new Abbreviation() { Pos = 51, ShortName = "ans.", LongName = "answer" });

        string test = "What is exp.? This is a test exp. in a para. contains ans. for a question";
        abbreviations.ForEach(x => ...); // Need a LINQ expression
        Console.WriteLine(test);
    }
}
公共类缩写
{
公共int Pos{get;set;}
公共字符串短名称{get;set;}
公共字符串LongName{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
列表缩写=新列表();
Add(新缩写(){Pos=28,ShortName=“exp.”,LongName=“expression”});
缩写词.Add(新缩写词(){Pos=38,ShortName=“para.”,LongName=“paragration”});
缩写词.Add(新缩写词(){Pos=51,ShortName=“ans.”,LongName=“answer”});
string test=“什么是exp.?这是段落中的测试exp.包含问题的答案”;
缩写.ForEach(x=>…);//需要一个LINQ表达式
控制台写入线(测试);
}
}
在LINQ中如何做到这一点?

好的,这个怎么样:

  public static void Main()
    {
        //var search = new Regex(@"spell\ correction", RegexOptions.IgnoreCase);
        //var data = "this is a teit that i see that";

        List<Abbreviation> abbreviations = new List<Abbreviation>();
        abbreviations.Add(new Abbreviation() { Pos = 29, ShortName = "exp.", LongName = "expression" });
        abbreviations.Add(new Abbreviation() { Pos = 39, ShortName = "para.", LongName = "paragraph" });
        abbreviations.Add(new Abbreviation() { Pos = 54, ShortName = "ans.", LongName = "answer" });

        string test = "What is exp.? This is a test exp. in a para. contains ans. for a question";
        var offset = 0;
        abbreviations.ForEach(x => {

            if(test.Substring(x.Pos+ offset, x.ShortName.Length)==x.ShortName)
            {

                test = test.Remove(x.Pos + offset, x.ShortName.Length);
                test= test.Insert(x.Pos  + offset, x.LongName);
                offset += x.LongName.Length - x.ShortName.Length ;
            }

        }); // Need a LINQ expression
        Console.WriteLine(test);
    }
publicstaticvoidmain()
{
//var search=newregex(@“拼写\更正”,RegexOptions.IgnoreCase);
//var data=“这是我看到的一个消息”;
列表缩写=新列表();
Add(新缩写(){Pos=29,ShortName=“exp.”,LongName=“expression”});
缩写词.Add(新缩写词(){Pos=39,ShortName=“para.”,LongName=“paration”});
缩写词.Add(新缩写词(){Pos=54,ShortName=“ans.”,LongName=“answer”});
string test=“什么是exp.?这是段落中的测试exp.包含问题的答案”;
var偏移=0;
缩写。ForEach(x=>{
if(测试子字符串(x.Pos+偏移量,x.ShortName.Length)==x.ShortName)
{
test=test.Remove(x.Pos+偏移量,x.ShortName.Length);
测试=测试插入(x.Pos+偏移量,x.LongName);
偏移量+=x.LongName.Length-x.ShortName.Length;
}
});//需要一个LINQ表达式
控制台写入线(测试);
}

请记住,如果您直接在源代码处替换缩写,则要替换的下一个缩写的位置索引将与您在开头声明的位置索引不同。所以我认为你需要一些辅助变量来做这件事

而且,你的起始索引有点偏离了目标

EDIT-将LINQ
ForEach
替换为常规的
ForEach
,这样使用它不支持的方法,例如
String.IsNullOrEmpty()

公共类缩写
{
公共int Pos{get;set;}
公共字符串短名称{get;set;}
公共字符串LongName{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
列表缩写=新列表();
Add(新缩写(){Pos=29,ShortName=“exp.”,LongName=“expression”});
缩写词.Add(新缩写词(){Pos=39,ShortName=“para.”,LongName=“paration”});
缩写词.Add(新缩写词(){Pos=54,ShortName=“ans.”,LongName=“answer”});
string test=“什么是exp.?这是段落中的测试exp.包含问题的答案”;
字符串temp=“”;
int-tempPos=0;
foreach(缩写中的缩写x)
{
如果(!String.IsNullOrEmpty(test)&&(test.Length>=x.Pos+x.ShortName.Length)&&test.Substring(x.Pos,x.ShortName.Length)==x.ShortName)
{
temp+=测试子字符串(tempPos,x.Pos)+x.LongName;
}
tempPos=x.Pos+x.ShortName.Length;
}
控制台写入线(临时);
}
}

So
Pos
对应于字符串中的位置?意思是如果
exp.
不在第30位,则应忽略它(即不替换)?是的,没错,您当前的代码工作吗?是第一个“exp.”位置8?您应提供一个清晰的列表,列出您尝试过的内容,以及清晰的输入、输出。我建议对你的问题进行进一步的阐述,以便于人们理解这个问题。仅供参考。通常,问题越漂亮,答案就越漂亮。半途而废的问题=半途而废的答案。不要使用
.ForEach()
,只需使用
ForEach
循环即可。他没有具体说明你需要考虑抵消?你只是从谁那里推断出来的。但他并没有提供足够的背景来证明这一点。但是,除此之外,我会做这项工作。然而,为什么不简单地解决最初的问题,因为他提供了错误的起始位置,只是从中减去一个呢?假设你为一个知道自己在做什么的人编写了这个程序,他们开始按照你的预期从零开始计数。这个答案会搞乱他们的代码。有一个服务返回缩写列表,其中包括单词替换的顺序,因此颠倒列表可以避免重新调整位置。我的问题得到了回答,谢谢。起初,我想知道使用LINQ表达式进行字符串操作的任何超高效方法。如果LINQ不喜欢内部逻辑,因为它不支持从
System.string派生的汇编方法,我们可以使用标准的
foreach
来代替。您应该只使用常规的
foreach
循环
List.ForEach()
总是一个坏消息idea@maccettura是的,我也不太清楚为什么LINQ不能访问/不引用其他基本组装方法。
public class Abbreviation
{
    public int Pos { get; set; }
    public string ShortName { get; set; }
    public string LongName { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        List<Abbreviation> abbreviations = new List<Abbreviation>();
        abbreviations.Add(new Abbreviation() { Pos = 29, ShortName = "exp.", LongName = "expression" });
        abbreviations.Add(new Abbreviation() { Pos = 39, ShortName = "para.", LongName = "paragraph" });
        abbreviations.Add(new Abbreviation() { Pos = 54, ShortName = "ans.", LongName = "answer" });

        string test = "What is exp.? This is a test exp. in a para. contains ans. for a question";

        string temp = "";
        int tempPos = 0;

        foreach (Abbreviation x in abbreviations)
        {
            if (!String.IsNullOrEmpty(test) && (test.Length >= x.Pos + x.ShortName.Length) && test.Substring(x.Pos, x.ShortName.Length) == x.ShortName)
            {
                temp += test.Substring(tempPos, x.Pos) + x.LongName;
            }
            tempPos = x.Pos + x.ShortName.Length;
        }
        Console.WriteLine(temp);
    }
}