匹配 .NET Regex 中的扩展 ASCII 字符

Posted

技术标签:

【中文标题】匹配 .NET Regex 中的扩展 ASCII 字符【英文标题】:Matching extended ASCII characters in .NET Regex 【发布时间】:2015-05-06 23:35:51 【问题描述】:

我正在编写一个 .NET 正则表达式,它需要匹配除控制字符之外的所有 ASCII 和扩展 ASCII 字符。

为此,我查阅了 ASCII 表,似乎所有这些字符都有 x20 到 xFF 的 ASCII 编码。

所以我想

[\x20-\xFF]

应该能够匹配我需要的所有字符。然而,实际上,有些字符可以匹配,而有些则不能。比如用在线工具http://regexhero.net/tester/测试,或者写一个简单的C#程序,你会发现有些字符如“ç”(xE7)可以匹配,但有些字符如“œ”(x9C)不能。

有人知道为什么正则表达式不起作用吗?

【问题讨论】:

我已经从 questuin 中复制了您的 œ 符号并通过 (int) 'œ 检查它,它显示 339 (0x153) 超出范围。 “Extended ASCII”是上个世纪的一个错误,造成了代码页灾难。 .NET 使用 Unicode。你将不得不重现灾难。 【参考方案1】:

我尝试重现您的错误,发现您的代码没有错

String pattern = @"[\x20-\xFF]";

// All ANSII 
for (Char ch = ' '; ch <= 255; ++ch)
  if (!Regex.IsMatch(ch.ToString(), pattern)) 
    Console.Write("Failed!");

// All non-ANSII
for (Char ch = (Char)256; ch < Char.MaxValue; ++ch)
  if (Regex.IsMatch(ch.ToString(), pattern)) 
    Console.Write("Failed!");

然后我检查了你的样本:

 ((int)'ç').ToString("X2"); // <- returns E7, OK
 ((int)'œ').ToString("X2"); // <- returns 153 NOT x9C 

注意,'œ' (x153) 实际上是 [0x20..0xFF] 之外,这就是匹配返回false 的原因。所以我猜你有一个错字

【讨论】:

非常感谢。我意识到 .Net 正则表达式中的数值是 Unicode 编码值,而不是扩展 ascii。在 Unicode 中,– 是 x153,在扩展 ASCII 中是 x9C。【参考方案2】:

正如我写的https://***.com/a/18131886/613130,你可以使用

var enc = Encoding.GetEncoding("ISO-8859-1");

将字节编码为使用相同代码的字符串:

string str = enc.GetString(yourBytes);

然后您可以使用您编写的正则表达式。请注意,我正在做的是作弊:“ASCII”信息太少。您需要告诉我您使用的是什么代码页,因为块 80-FF 可以以各种方式映射,具体取决于位置(“代码页”),所以œ 不是所有地方都是9C,如果你看看那个编码器生成的字符串,你不会得到œ,但你会得到一个代码为0x9C的字符。

如果您想要一个与您拥有的文本“打印”相同的 C# 字符串,您需要使用

var enc = Encoding.GetEncoding("Windows-1252");

(它是 ISO-8859-1 的 MS 扩展,包含 0x9C 处的 œ 字符)

但请注意,在这种情况下,您将无法使用如此简单的正则表达式,因为您的 80-FF 代码将被映射到 0000-FFFF unicode 字符周围

啊...显然您可以通过以下方式避开这个问题:

[^\x00-\x19]

(不是 0x00-0x19):-)

【讨论】:

以上是关于匹配 .NET Regex 中的扩展 ASCII 字符的主要内容,如果未能解决你的问题,请参考以下文章

在 RegEx 中,表达式 \X 匹配啥?

Java 和 .NET 之间的 RegEx“匹配”不同

redshift regex 获取多个匹配项并扩展行

.NET Regex 是不是支持全局匹配?

使用 Regex 和 AltSearch 删除空行

C:基于GNU regex(regex.h)regexec实现正则表达式多次匹配