繁体   English   中英

c#用包含未知部分的替换字符串

[英]c# Replace string with does contains unknown parts

我有一个包含文本的文件。 现在,我必须用另一个替换一些字符串。 例如,我必须更换

"[ContactLetterSalutation]" 

 "Dear Thomas Kehl". 

现在,占位符"[ContactLetterSalutation]"包含某个地方"=\\r\\n" - 这可能是一次,两次或更多次 - 例如

"[Conta=\r\ntLetterSa=\r\nlutation]".

我现在正在寻找一种方式,我也可以替换它 - 我不知道会在哪里和有多少次"=\\r\\n" 困难的是,我不应该在文本中替换所有出现的"=\\r\\n" 有人可以帮我怎么做? 是否有可能使用RegEx执行此操作?

谢谢。 最诚挚的问候,托马斯

  • 使用正则表达式搜索括号内的任何内容。
  • 对于每个匹配,请删除所有= \\ r \\ n以查找密钥。
  • 将匹配替换为值。

例:

  • 你搜索[ 任何 ]
  • 你找到[Conta=\\r\\ntLetterSa=\\r\\nlutation]
  • 您使用密钥ContatLetterSalutation来查找正确的值。
  • 用该值替换[Conta=\\r\\ntLetterSa=\\r\\nlutation]
string GetReplacement(Match m) {
    // Get the matched string.
    string x = m.ToString().Replace("=\r\n","");
    return Lookup[x];
}

...
file = Regex.Replace(file, @"\[.*?\]", GetReplacement, RegexOptions.Singleline);
编辑:

RegexOptions.Singleline导致。 匹配\\ n

EDIT2:

虽然以上内容适用于小文件,但我认为这个问题对于无法将整个文件放入单个字符串的流更有趣。 我想出了这个,但它可能有错误:

 static IEnumerable<string> Chunk(TextReader reader) { char[] chars = new char[MaxBufferSize]; string buffer = ""; int charsRead; while ((charsRead = reader.ReadBlock(chars, 0, MaxBufferSize)) > 0) { buffer = buffer + new string(chars,0,charsRead); int indexOfOpenBracket; if((indexOfOpenBracket = buffer.IndexOf('[')) == -1) { if (!string.IsNullOrEmpty(buffer)) yield return buffer; buffer = ""; continue; } while (indexOfOpenBracket!=-1) { string outsideBrackets = buffer.Substring(0, indexOfOpenBracket); if(!string.IsNullOrEmpty(outsideBrackets)) yield return outsideBrackets; buffer = buffer.Substring(indexOfOpenBracket + 1); int indexOfCloseBracket = buffer.IndexOf(']'); if (indexOfCloseBracket != -1) { string insideBrackets = buffer.Substring(0, indexOfCloseBracket); buffer = buffer.Substring(indexOfCloseBracket + 1); yield return DoLookup(insideBrackets); } else { buffer = '[' + buffer; break; } indexOfOpenBracket = buffer.IndexOf('['); } } yield return buffer; } public static void BufferReplace(Stream input, Stream output) { StreamReader reader = new StreamReader(input); StreamWriter writer = new StreamWriter(output); foreach (var chunk in Chunk(reader)) { writer.Write(chunk); } writer.Flush(); } 

是的,你可以用正则表达式做到这一点。 我不会试图在一次通过中实现这一点。 我假设您有一个HashTable或其他存储,您可以在其中查找占位符字符串以获取要放在其中的文本。 另外我假设您想要从C#代码执行此操作,有一个工具调用sed,它将从unix / linux或cygwin underwindows中的命令行执行此操作。 它适用于正则表达式。

在制作正则表达式时,我喜欢使用这个网站: http//regexpal.com/

所以首先你尝试找到占位符中带有不需要的\\ r \\ n的模式:“\\ [([^ \\]] +)\\]”这将找到任何以[至少有一个]开头的模式不是]并以]结尾的字符。

获得匹配列表后,您可以在将其用于查找之前删除不需要的模式。

这是一个非常简单的小例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            String textFromFile = "some text [re=\r\npla=\r\nme] more [Anoth=\r\ner=\r\n place=\r\n=\r\n=\r\n holder] text";

            foreach (Match match in Regex.Matches(textFromFile, "\\[([^\\]]+)\\]"))
            {
                String placeHolder = match.Groups[1].Value.Replace("=\r\n", "");
                // *** Do rest of your work here ***.
                System.Console.WriteLine(placeHolder);
            }
        }
    }
}

该程序打印出来:

replaceme
Another place holder

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM