如何替换许多基于文本的文件中的变量值

时间:2011-08-28 13:32:51

标签: c# replace

我需要一个脚本/程序/替换许多基于文本的文件中的特定变量值。 我认为正则表达式是关键字,但不是那么多......

更准确地描述问题:

文件中的原始代码:

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

大家好, Thanx很多你的所有帖子都会让我看到这个看起来很有效的结果:

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

现在我只需要找出困难的部分 - 使上面的代码在textfile上工作..:)

干杯! 的Mikkel

4 个答案:

答案 0 :(得分:1)

你可以使用记事本++“在文件中查找”功能(ctrl h)

您可以搜索文字POTATO = -3000; POTATO = 1020; !this value is updated 2011-08-28

选择包含所有文件的dircetory并选中“在所有子文件夹中”

并替换为(5000 added to the variable): POTATO = 2000; POTATO = 6020; !this value is updated 2011-08-28

答案 1 :(得分:0)

使用正则表达式是您的关键,使用Matchevaluator委托将每个匹配转换为intlong,然后将conversion添加到该字符串:< / p>

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指出模式中的错误导致结果在=符号后吞下空格,这是打印{{ 1}}而不是POTATO =2000;

答案 2 :(得分:0)

你可以这样做:

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

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

这会创建一个匹配可选减号(-?)后跟一个或多个十进制数字(\d+)的正则表达式,但前提是它前面跟着字符串POTATO =({{ 1}})后跟一个分号(?<=^POTATO = )。然后它使用lambda将匹配的值转换为(?=;),为其添加5000并将其转换回int

答案 3 :(得分:0)

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