我需要一个脚本/程序/替换许多基于文本的文件中的特定变量值。 我认为正则表达式是关键字,但不是那么多......
更准确地描述问题:
文件中的原始代码:
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
答案 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
委托将每个匹配转换为int
或long
,然后将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 );
}