简体   繁体   中英

c# Replace string with does contains unknown parts

I have a File, which contains text. Now, I have to replace some string with another. For Example I have to replace

"[ContactLetterSalutation]" 

with

 "Dear Thomas Kehl". 

Now, it is possible, that the placeholder "[ContactLetterSalutation]" contains somewhere "=\\r\\n" - this could be one, two or more times - for example

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

I am searching now a way, that I can also replace this - I don't know where and how many times there will be "=\\r\\n" . The difficult is, that I should not replace all occurrences of "=\\r\\n" in the text. Can someone help me how to do this? Is there perhaps a possibility to do this with RegEx?

Thank you. Best Regards, Thomas

  • Search for anything within brackets, using a regex.
  • For every match, remove all =\\r\\n to find the key.
  • Replace the match with the value.

Example:

  • You search for [ anything ] .
  • You find [Conta=\\r\\ntLetterSa=\\r\\nlutation] .
  • You use the key ContatLetterSalutation to find the correct value.
  • You replace [Conta=\\r\\ntLetterSa=\\r\\nlutation] with that value.
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);
edit:

RegexOptions.Singleline causes . to match \\n

edit2:

While the above should work for small files, I think this question is more interesting for streams where you couldn't get the whole file into a single string. I've come up with this but it probably has bugs:

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

Yes you can do this with regex. I would not try to make that happen in one pass. I assume that you have an HashTable or other storage where you can lookup the placeholder string to get the text you want to put in its place. Also I am assuming you want to do this from C# code, there is a tool call sed that wil do this from the command line in unix/linux or cygwin underwindows that does it. and it works with regular expressions.

when working out regex expressions I like to use this site: http://regexpal.com/

so first you try and find the pattern for the place holder with the unwanted \\r\\n in it: "\\[([^\\]]+)\\]" this will find any pattern that starts with a [ has at least one character that is not ] and ends with ].

once you have the list of matches you can work on removing the pattern you do not want before using it for your lookup.

here is a very simple little example:

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

This program prints out:

replaceme
Another place holder

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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