【问题标题】:regex to match special character ????正则表达式匹配特殊字符????
【发布时间】:2021-11-03 06:01:01
【问题描述】:

我正在处理的一个文本文件中有很多特殊字符(行终止符:LF;文件编码:utf-8),其中两个是????和 ????。它们对应的十六进制代码是\xf4\x80\x91\x9a\xf4\x80\x91\x9d

出于测试目的,您可以将以下文本放入文本文件 1.txt:a ???? and a ???? at the line end 或者您可以使用此文件: https://drive.google.com/file/d/1E-8oZaLb86x0JE_gFpTkeX9jrbh3OXbF/view?usp=sharing

在像 Sublime 这样的编辑器中,我无法使用它们的十六进制代码匹配这些特殊字符。 不确定是否有其他方法可以做到这一点。

使用 perl,我也无法匹配它们。我想使用正则表达式删除所有这些类似汉堡包的字符:

perl -Mutf8::all -pE's,\xf4\x80\x91\x9a,,g; s,\xf4\x80\x91\x9d,,g;' 1.txt > 2.txt

有什么办法可以做到吗?

【问题讨论】:

  • 这些是 UTF-8 编码的字符吗?根据this page "\xf4\x80\x91\x9a" 不是有效的 unicode 字符。
  • 您提供的信息不足 -- 文件的来源是什么?在 Windows 10 中,notepad++ - 标记您尝试替换的符号,按 Ctrl+H 并输入替换(在您的情况下为空)按 Replace all - 完成。对第二个符号重复相同的过程。注意:也许这些符号是 UTF-16x 或 UTF-32 编码——不知道文件的来源不可能确定。
  • 您可以尝试以dirty trick 的身份使用s/(????|????)//g;,但您仍然需要正确读取文件并指出它的编码。
  • 这个perl -wE'$hc = "\xf4\x80\x91\x9a"; $s = "hi".$hc; say $s; $s =~ s{$hc}{}g; say $s' 适合我。我错过了什么……?
  • @Polar Bear 确实我可以复制符号并替换。这些符号看起来相同,但实际上并不相同。所以我想知道是否有某种方法可以一劳永逸地使用正则表达式替换它们。

标签: regex perl


【解决方案1】:

您可以尝试将文件读取为字节/二进制(使用:raw IO 层):

use feature qw(say);
use strict;
use warnings;

my $fn = 'test.txt';
open ( my $fh, '<:raw', $fn ) or die "Could not open file '$fn': $!";
my $txt = do { local $/; <$fh> };
close $fh;
my @replace = ("\xf4\x80\x91\x9a", "\xf4\x80\x91\x9d");
my ($pat ) = map {qr/$_/} join "|", map quotemeta, @replace;
$txt =~ s/$pat//g;
print $txt;

【讨论】:

  • 谢谢。这对两个特殊字符非常有效。是否有可能涵盖比两个特殊字符更多的情况?我只是尝试修改代码并将 $pat 部分更改为 my ($pat ) = qr/quotemeta('\xf4\x80\x91[\x9a-\x9d]')/; 。但它似乎不起作用。
  • 您不应该在应该被解释为正则表达式(而不是文字字符串)的正则表达式上使用quotemeta。相反,您可以使用普通的正则表达式,例如 my $pat = qr/\xf4\x80\x91[\x9a-\x9d]/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多