【问题标题】:Partial match with Regular Expression与正则表达式部分匹配
【发布时间】:2015-04-12 11:25:43
【问题描述】:

当正则表达式需要特定数量的字符时,有没有办法确定单个字符是否有效?

我有一个 WPF 自定义键盘,想根据正则表达式调整每个键的可用性。 当表达式相当简单并且不期望字符的特定顺序或特定长度来满足模式时,这将很有效。

但是,当模式变得更加复杂和具体时,针对它测试单个字符总是会失败。

例如,给定正则表达式[a-zA-Z0-9]{4}

这些值将成功:

  • ABCD
  • abcd
  • 1234
  • A23e

该表达式显然只需要字母数字字符。 我想要一种方法,给定表达式将拒绝特殊字符,比如“%”,但接受“a”,因为“a”在[a-zA-Z0-9] 中是可以接受的。唯一的问题是无法满足的具体长度。

我目前正在使用Regex.IsMatch。我想我正在寻找一种部分匹配测试方法。

【问题讨论】:

  • 我已将您的问题阅读了两遍,但我仍然不明白您想要做什么。也许只是替换所有不是字母数字的[^a-zA-Z0-9]+
  • @HamZa 我把它读作“我有没有可能最终(当添加更多字符时)满足给定的正则表达式的子字符串”。
  • 是的,我正在寻找部分匹配。如果表达式需要“abc”,我想要一个方法告诉我,用“a”我走在正确的轨道上,但用“1”却没有
  • @HamZa 但是“ab%d”会因为错误的字符而不是长度而失败 - 但是获得足够通用的填充字符串可能太复杂了(完全正确的)......无论如何我不相信有任何理智的方法可以部分匹配通用正则表达式 - 解析/重构可能是出于娱乐目的而需要研究的东西(但对于实际代码并不真正有用)
  • @Alexei 实际上有一种理智的方式 - 请参阅我的回答;)

标签: c# regex wpf character special-characters


【解决方案1】:

当然可以,但遗憾的是不能使用内置的正则表达式引擎。您可以改用PCRE,它提供了您要求的部分匹配功能。

来自 PCRE 文档:

在 PCRE 的正常使用中,如果传递给匹配函数的主题字符串尽可能匹配,但太短而无法匹配整个模式,则返回 PCRE_ERROR_NOMATCH。在某些情况下,将这种情况与其他不匹配的情况区分开来可能会有所帮助。

例如,考虑一个应用程序,其中需要人工为具有特定格式要求的字段输入数据。例如,ddmmmyy 形式的日期,由以下模式定义:

 ^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$

如果应用程序一一看到用户的击键,并且可以检查到目前为止所键入的内容是否可能有效,那么一旦出现错误,它就可以通过发出哔哔声而不反映字符来引发错误例如,已键入。与延迟到输入整个字符串的检查相比,这种即时反馈可能是更好的用户界面。当主题字符串很长并且不能一次全部可用时,部分匹配也很有用。

PCRE 通过PCRE_PARTIAL_SOFTPCRE_PARTIAL_HARD 选项支持部分匹配,可以在调用任何匹配函数时进行设置。为了向后兼容,PCRE_PARTIALPCRE_PARTIAL_SOFT 的同义词。这两个选项之间的本质区别是部分匹配是否比替代完全匹配更可取,尽管两种类型的匹配函数之间的细节有所不同。如果两个选项都设置了,PCRE_PARTIAL_HARD 优先。


但 PCRE 是一个 C 库...所以我构建了一个 PCRE wrapper for .NET

来自the readme的用法示例:

var regex = new PcreRegex(@"(?<=abc)123");
var match = regex.Match("xyzabc12", PcreMatchOptions.PartialSoft);
// result: match.IsPartialMatch == true

不过要小心一点:包装器目前是 v0.3,使用 PCRE v8.36,但最近发布了 PCRE v10.0(带有新的 API),所以预计 API 中会有一些重大更改 PCRE.NET v0.4 的 em>。不过,行为应该保持不变。

此外,您应该注意 .NET 和 PCRE 正则表达式之间的the differences。不过,在大多数情况下,这应该不是问题。

【讨论】:

  • 感谢卢卡斯的详细回答。我稍后会调查它。现在,由于我有一个相当小的正则表达式列表需要支持,我可能会创建一个物理文件,该文件将根据每个表达式映射启用哪些键。暂时这应该是足够动态的......
猜你喜欢
  • 2011-06-13
  • 1970-01-01
  • 2017-11-29
  • 2017-06-23
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 2020-01-02
相关资源
最近更新 更多