正则表达式匹配以特定数字开头的版本号





4.00/5 (1投票)
如何在具有特定匹配要求的正则表达式中使用插入符号 (^) 的示例
引言
我最近在工作中遇到了这样一个需求:可以访问一个充满配置文件的文件夹。
任务是修复一个替换文件版本号的脚本。
问题是脚本没有进行正确的替换,从而弄乱了依赖于配置文件的系统的运行。
一些包含但并非以特定数字开头的版本号的中间部分被替换了,而这并非预期的功能。
在本文中,我们将探讨如何重新编写脚本以正确识别需要更新的版本号。
背景
名为PostSharp的NuGet包非常有用。但是,其作者经常更新它。我们组织有一个要求,所有依赖于PostSharp NuGet包的软件必须始终使用最新版本。
截至撰写本文时,PostSharp的版本号为6.10.15
。我有很多packages.config文件需要更新其中的版本号,这样我就可以在命令行上执行nuget restore
来更新包。
因此,我想到了在LINQPad中编写一个C#脚本,该脚本将迭代root目录中的packages.config文件和*.csproj文件,并将文件中的版本号替换为从NuGet网站抓取的最新版本。
正则表达式(简称Regex)的困境
手头的任务
我试图匹配一个版本号(以便在各种config文件中替换它)。
我想匹配的版本号
- 始终由三个数字组成,包含
0-99
,用点号分隔 - 第一个数字始终是
6
例如,6.10.14
是一个示例版本号。
当前代码
为了进行替换,我使用了以下代码
public static class Update
{
private static string PostSharpVersionToLatest(string contents)
{
var result = string.Empty;
if (string.IsNullOrWhiteSpace(contents)) return result;
try
{
result =
Regex.Replace(
contents,
@"6\.\d+\.\d+",
LATEST_POSTSHARP_VERSION
);
result =
Regex.Replace(
result,
@"6\.\d+\.\d+\-rc",
LATEST_POSTSHARP_VERSION
);
}
catch (Exception ex)
{
Console.WriteLine(ex);
result = string.Empty;
}
return result;
}
}
用于查找和替换版本号的正则表达式是6\.\d+\.\d+
。
当时看起来像是正确的正则表达式。
但是,在我搜索和进行替换的文本文件中还有其他版本号,例如16.301.204959.29
等等。我使用的模式也匹配这些,而这并非我想要的结果。我只希望开头是6.
的匹配,而不是开头是16.
等的版本号也匹配。
不断发生的问题是,较长版本号中的6.301.204959
文本也被匹配并替换,这会导致packages.config文件损坏。
Regex Hero来救援
有一个非常方便的实用程序——我推荐你获取——叫做Regex Hero。
我将使用它来找出我的正则表达式有什么问题。显示使用正则表达式6\.\d+\.\d+
匹配目标字符串6.10.14
的Regex Hero窗口在**图1**中可见。
我们的模式似乎运行良好。但是,假设较长的版本号16.301.204959.29
也存在于我们正在进行查找和替换操作的文本文件中。
我们将它放入Regex Hero的**目标字符串**框中,使用**正则表达式**字段的相同值,并获得如**图2**所示的结果。
可以想象,如果我们尝试进行文本替换操作,而我们只想定位明确以6
开头而不是16
或36
等的版本号,这可能会导致问题。
使用脱字符号(^)
我知道我可以在正则表达式的开头使用脱字符号 (^
)。根据这篇博文
引用你可以在正则表达式的开头使用脱字符号(^)来指示匹配必须出现在被搜索文本的开头。
我的想法是尝试以下正则表达式:^6\.\d+\.\d+
。正如在Regex Hero中看到的,版本号16.301.204959.29
没有匹配,如图3所示。
让我用我的新正则表达式尝试示例版本号6.10.14
,如图4所示。
结论
我们可以看到,通过在正则表达式的开头使用脱字符号^
,可以解决创建仅匹配以特定数字开头的值的正则表达式的問題。
历史
- 2022年8月20日:初始版本