我尝试对以下字符串执行正则表达式:
040A0000 02CCDAD0 F9401401
040A0000 02CCDAD4 F8410021
040A0000 02CCDAD8 B4000041
040A0000 02CCDADC 52800015
040A0000 02CCDAE0 2A1503E1
040A0000 02CCDAE4 17DA29B5
Run Code Online (Sandbox Code Playgroud)
我的目标是检索最后一个 8 个字符块,无论它前面有多少个字符。我正在使用以下模式:
^(([\d\w]+ ){1,})?([\d\w]+)$
现在,根据 regex101,这种模式应该可以正常工作: https: //regex101.com/r/ZuWIPV/1
但是,当运行以下代码时:
var reg = new Regex("^(([\\d\\w]+ ){1,})?([\\d\\w]+)$", RegexOptions.Multiline);
if (reg.IsMatch(textBox1.Text))
{
var instructions = reg.Matches(textBox1.Text).Cast<Match>().Select(x => x.Groups[3].Value).ToArray();
foreach (var instruction in instructions)
{
MessageBox.Show(instruction);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的唯一结果是最后一行:
17DA29B5
我本来希望得到全部 6 个,如下所示:
F9401401
F8410021
B4000041
52800015
2A1503E1
17DA29B5
Run Code Online (Sandbox Code Playgroud)
首先,您不需要使用[\w\d]as\w也匹配数字。接下来,当您在 C# 中定义正则表达式时,应该使用逐字字符串文字以避免过度转义。另外,仅当需要节省一些性能时才使用捕获组。
问题是您忘记在每行末尾匹配可选的 CR 字符。请参阅多行模式MSDN 正则表达式参考
默认情况下,
$仅匹配输入字符串的末尾。如果指定RegexOptions.Multiline选项,它将匹配换行符 (\n) 或输入字符串的末尾。但是,它与回车/换行字符组合不匹配。要成功匹配它们,请使用子表达式\r?$而不是仅使用$。
您可以使用
var reg = new Regex(@"^(?:\w+ )*(\w+)\r?$", RegexOptions.Multiline);
Run Code Online (Sandbox Code Playgroud)
要支持行上的任何空格,您可以使用
var reg = new Regex(@"^(?:\w+[\p{Zs}\t])*(\w+)\r?$", RegexOptions.Multiline);
Run Code Online (Sandbox Code Playgroud)
其中[\p{Zs}\t]匹配任何水平空白。
如果您只想匹配每行末尾的最后 8 个 ASCII 十六进制字符,您可以使用
var reg = new Regex(@"[a-fA-F0-9]{8}\r?$", RegexOptions.Multiline);
Run Code Online (Sandbox Code Playgroud)
.NET 中的注释\w匹配所有Unicode字母、数字、连接标点符号,甚至变音符号,因此在这种情况下它可能不是最佳选择。唉,.NET 正则表达式没有十六进制字符的简写,就像%xLua、[[:xdigit:]]POSIX BRE/ERE、\p{XDigit}Java 等一样。
为什么 regex101.com 显示正确的匹配项?
在 regex101.com,所有换行符均为 LF,但在 Windows 上的 C# 中,行结尾大多为 CRLF。但是,$在多行中仅匹配 LF 字符之前。
当您需要测试 .NET 正则表达式时,使用 regex101.com 来验证模式并不是一个好主意,因为此正则表达式测试站点不支持 .NET 正则表达式语法(和 Linux 行结尾)。您可以使用RegexStorm.net,其中换行符设置为 CRLF。
| 归档时间: |
|
| 查看次数: |
72 次 |
| 最近记录: |