c # Заменить строку на содержит неизвестные части - PullRequest
3 голосов
/ 25 июня 2011

У меня есть файл, который содержит текст. Теперь я должен заменить одну строку другой. Например, я должен заменить

"[ContactLetterSalutation]" 

с

 "Dear Thomas Kehl". 

Теперь возможно, что заполнитель "[ContactLetterSalutation]" содержит где-то "=\r\n" - это может быть один, два или более раз - например,

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

Сейчас я ищу способ, которым я также могу заменить это - я не знаю, где и сколько раз будет "=\r\n". Сложность в том, что я не должен заменять все вхождения "=\r\n" в тексте. Может кто-нибудь помочь мне, как это сделать? Возможно ли сделать это с помощью RegEx?

Спасибо. С наилучшими пожеланиями, Томас

Ответы [ 3 ]

6 голосов
/ 25 июня 2011
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();
}
6 голосов
/ 25 июня 2011
  • Ищите что-либо в скобках, используя регулярное выражение.
  • Для каждого совпадения удалите all = \ r \ n, чтобы найти ключ.
  • Замените совпадение значением.

Пример:

  • Вы ищете [ что-нибудь ].
  • Вы найдете [Conta=\r\ntLetterSa=\r\nlutation].
  • . Вы используете ключ ContatLetterSalutation, чтобы найти правильное значение.
  • Вы заменяете [Conta=\r\ntLetterSa=\r\nlutation] на это значение.
1 голос
/ 25 июня 2011

Да, вы можете сделать это с помощью регулярных выражений.Я бы не стал делать это за один проход.Я предполагаю, что у вас есть 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...