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

时间:2011-06-25 12:17:32

标签: c# regex replace

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

"[ContactLetterSalutation]" 

 "Dear Thomas Kehl". 

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

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

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

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

3 个答案:

答案 0 :(得分:6)

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

示例:

  • 您搜索[ 任何内容 ]
  • 您找到[Conta=\r\ntLetterSa=\r\nlutation]
  • 您使用密钥ContatLetterSalutation查找正确的值。
  • 您将[Conta=\r\ntLetterSa=\r\nlutation]替换为该值。

答案 1 :(得分:6)

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();
}

答案 2 :(得分:1)

是的,您可以使用正则表达式执行此操作。我不会试图在一次通过中实现这一点。我假设您有一个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