linux 正则 mac,正则表达式 - RE错误:Mac OS X上的非法字节序列

博客内容涉及到字符编码问题,特别是ISO-8859-1与UTF-8之间的转换。文章指出,当输入文件的编码与shell编码不匹配时,会触发'非法字节序列'的错误。解决方案包括使用LC_ALL=C来忽略非ASCII字符,或者使用iconv进行编码转换。文章还提供了示例命令来演示如何识别和处理无效字节,以及如何在处理后恢复到原始编码。
摘要由CSDN通过智能技术生成

显示症状的示例命令:ISO-8859-1失败,因为字节iconv不是有效的UTF-8字符。

请注意,相比之下,GNU UTF-8(Linux,但也可以在macOS上安装)只是传递无效字节,而不报告错误。

如果您不介意失去对真实语言环境的支持,那么使用之前接受的答案是一种选择(如果您使用的是美国系统而且您永远不需要处理外国字符,那可能没问题。)

但是,对于单个命令,ad-hoc也可以产生相同的效果:

LC_ALL=C sed -i "" 's|"iphoneos-cross","llvm-gcc:-O3|"iphoneos-cross","clang:-Os|g' Configure

注意:重要的是有效ISO-8859-1设置为iconv,因此UTF-8通常也可以工作,但如果碰巧设置iconv -l(除了\x{e0}之外的其他东西),它将覆盖单个LC_*类别变量,例如LC_CTYPE。因此,最重要的是 健全的方法是设置LC_ALL。

但是,(有效地)将ISO-8859-1设置为iconv将字符串视为每个字节都是其自己的字符(不执行基于编码规则的解释),而不考虑OS X使用的 - 多字节按需 - UTF-8编码 默认情况下,外部字符具有多字节编码。

简而言之:将ISO-8859-1设置为iconv会导致shell和实用程序仅将基本英文字母识别为字母(7位ASCII范围内的字母),以便外部字符。 不会被视为字母,例如导致大写/小写转换失败。

同样,如果您不需要匹配多字节编码的字符(例如ISO-8859-1),并且只是想传递这些字符,这可能会很好。

如果这不够和/或您想了解原始错误的原因(包括确定导致问题的输入字节)并按需执行编码转换,请阅读下文。

问题是输入文件的编码与shell的编码不匹配。

更具体地说,输入文件包含以UTF-8无效的方式编码的字符(如评论中所述@KlasLindbäck) - 这是ISO-8859-1错误消息试图通过iconv说的。

最有可能的是,您的输入文件使用单字节8位编码,例如ISO-8859-1,经常用于编码“西欧”语言。

例:

带有重音的字母ISO-8859-1具有Unicode代码点iconv(224) - 与UTF-8中的相同。但是,由于UTF-8编码的性质,此单个代码点表示为2个字节 - iconv -l,而尝试传递单个字节\x{e0}则 在UTF-8下无效。

以下是使用编码为ISO-8859-1的字符串ISO-8859-1进行演示的示例,其中UTF-8表示为一个字节(通过ANSI-C引用的bash字符串(iconv -l),使用\x{e0}创建字节):

请注意,ISO-8859-1命令实际上是一个简单地传递输入的无操作,但是我们需要它来激发错误:

# -> 'illegal byte sequence': byte 0xE0 is not a valid char.

sed 's/.*/&/' <<

要简单地忽略该问题,可以使用上述ISO-8859-1方法:

# No error, bytes are passed through ('á' will render as '?', though).

LC_CTYPE=C sed 's/.*/&/' <<

如果要确定输入的哪些部分导致问题,请尝试以下操作:

# Convert bytes in the 8-bit range (high bit set) to hex. representation.

# -> 'voil\x{e0}'

iconv -f ASCII --byte-subst='\x{%02x}' <<

输出将以十六进制形式显示所有具有高位设置(超过7位ASCII范围的字节)的字节。 (但是,请注意,还包括正确编码的UTF-8多字节序列 - 需要更复杂的方法来专门识别UTF-8字节中的无效字节。)

按需执行编码转换:

标准效用ISO-8859-1可用于转换(iconv)和/或(UTF-8)编码; iconv -l列出了所有受支持的。

例子:

将shell从ISO-8859-1转换为shell中有效的编码(基于iconv,默认情况下为UTF-8),基于上面的示例:

# Converts to UTF-8; output renders correctly as 'voilà'

sed 's/.*/&/' <<

请注意,此转换允许您正确匹配外来字符:

# Correctly matches 'à' and replaces it with 'ü': -> 'voilü'

sed 's/à/ü/' <<

要在处理后将输入BACK转换为ISO-8859-1,只需将结果传递给另一个iconv命令:

sed 's/à/ü/' <<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值