Как заменить значения переменных во многих текстовых файлах - PullRequest
2 голосов
/ 28 августа 2011

Мне нужен скрипт / программа / что угодно, чтобы заменить определенные значения переменных во многих текстовых файлах.Я думал, что ключевым словом было регулярное выражение, но не столько в этом ...

Более точное описание проблемы:

Оригинальный код в файле:

POTATO = -3000;
POTATO = 1020;    !this value is updated 2011-08-28

Код после «преобразования» (5000 добавлено к переменной):

POTATO = 2000;
POTATO = 6020;    !this value is updated 2011-08-28

Выше приведен пример в уменьшенном масштабе, поскольку переменная POTATO имеет много различных значений во многих различных файлах..

Пожалуйста, сообщите!Mikkel

Привет всем, большое спасибо за все ваши посты, которые привели меня к этому результату, который, кажется, работает блестяще:

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

class test
{

    static void Main()
    {
        ShowOutput("TOMATO =-2000");
        ShowOutput("POTATO =-2000");
        ShowOutput("POTATOO = 5000");
        ShowOutput("TOMATO =-2000");
        ShowOutput("POTATO = -2000 'This is a nice value");
        ShowOutput("POTATO =-2000 'This is also a nice value");
    }

    public static void ShowOutput(string InputStreng)
    {
        Console.WriteLine("BEFORE: " + InputStreng);
        Console.WriteLine("AFTER: " + IncrementValues(InputStreng, 1));
        Console.WriteLine();
        Console.ReadLine();
    }

    private static string IncrementValues(string input, int increment)
    {
        string pattern = @"(?<=POTATO =\s*)(-?\d+)";
        var regex = new System.Text.RegularExpressions.Regex(pattern,
        System.Text.RegularExpressions.RegexOptions.Multiline);

        return regex.Replace(input, delegate(Match match)
        {
            long value = Convert.ToInt64(match.Groups[1].Value);
            return (value + 5000).ToString();
        });
    }
 }

Теперь мне просто нужно разобраться в сложной части - делая вышекод работы над текстовым файлом ..:)

Ура!Миккель

Ответы [ 4 ]

1 голос
/ 28 августа 2011

вы можете использовать notepad ++ функцию "найти в файлах" (ctrl h)

вы можете искать текст POTATO = -3000; POTATO = 1020; !this value is updated 2011-08-28

выбрать каталог, в котором есть все файлы, и отметьте "ввсе подпапки "

и заменить на (5000 added to the variable): POTATO = 2000; POTATO = 6020; !this value is updated 2011-08-28

0 голосов
/ 28 августа 2011

RegEx является хорошим решением для этого типа проблемы.Думаю, я бы добавил альтернативу, которая использует рекурсию и строки, если у вас есть RegExPhobia .

Здесь есть несколько предположений, например, строка, предшествующая целому числу для обновления, всегда будет иметь тот же формат xxxx<space>=<space>value;.И значение после имени переменной всегда является целым числом, за которым следует точка с запятой.Если это не всегда так, то метод может быть изменен для соответствия сценариям этих типов.

private void SomeMethod( ... )
{
    string str = GetTextFile( ... ); // read text file into a string

    // 2nd param should include the space before and after the = sign.
    string updated = UpdateValue( str, "potato = ", 5000, 0 );

    UpdateTextFile( ... ); // update the original text file
}

/// <summary>
/// Updates the value of all integer values in a string that
/// are preceeded by the string to <param name="match"></param>.
/// Uses recursion to update all values.
/// </summary>
/// <param name="original">Entire original string.</param>
/// <param name="match">Phrase preceeding the value to update.</param>
/// <param name="increaseBy">Amount to increase the variable by.</param>
/// <param name="startIndex">Index of the original string to start looking
/// for the <param name="match"></param> phrase. Index should always
/// be 0 when calling method for first time. <param name="startIndex"></param> 
/// will be updated automatically through recursion.
/// </param>
private static string UpdateValue( string original, string match, int increaseBy, int startIndex )
{
    string skip = original.Substring( 0, startIndex );
    string fragment = original.Substring( startIndex );

    int start = fragment.IndexOf( match, StringComparison.OrdinalIgnoreCase );
    if( start == -1 )
    {
        return original;
    }

    start = start + match.Length;

    int end = fragment.IndexOf( ";", start );

    if( end == -1 )
    {
        return original;
    }

    string left = fragment.Substring( 0, start );

    string right = fragment.Substring( end );

    string value = fragment.Substring( start, end - start );

    int newValue = int.Parse( value ) + increaseBy;

    string str = skip + left + newValue + right;

    return UpdateValue( str, match, increaseBy, startIndex + end );
}
0 голосов
/ 28 августа 2011

Вы можете сделать это так:

var re = new Regex(@"(?<=^POTATO = )-?\d+(?=;)", RegexOptions.Multiline);

var result = re.Replace(s, m => (int.Parse(m.Value) + 5000).ToString());

Это создает регулярное выражение, которое соответствует необязательному минусу (-?), за которым следуют одна или несколько десятичных цифр (\d+), но только если ему предшествует строка POTATO = ((?<=^POTATO = )) и затем следует точка с запятой (?=;). Затем он использует лямбду, чтобы преобразовать соответствующее значение в int, добавить к нему 5000 и преобразовать обратно в string.

0 голосов
/ 28 августа 2011

Использование Regular Expression - ваш ключ, используйте делегат Matchevaluator для преобразования каждого соответствия в int или long, а затем добавьте conversion к этой строке:

private sting IncrementValues(string input, int increment)
{
    //assuming your input is: POTATO = -3000;
    //                        POTATO = 1020;    !this value is updated 2011-08-28";

    string pattern = @"(?<=(^|\s)POTATO = )(-?\d+)(?=;)";

    var regex = new System.Text.RegularExpressions.Regex(pattern, 
    System.Text.RegularExpressions.RegexOptions.Multiline);

    return regex.Replace(input, delegate(Match match)
    {
        long value = Convert.ToInt64(match.Groups[1].Value);

        return (value + 5000).ToString();
    });
}

результат будет:

POTATO = 2000;
POTATO = 6020;    !this value is updated 2011-08-28

Редактировать: Я обновил шаблон поиска, благодаря @svick, чтобы указать на ошибку в шаблоне, которая приводила к тому, что результаты глотали пробелы после знака =, вместо него печатались POTATO =2000;POTATO = 2000;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...