如何从 XML 字符串或文件中删除表情符号,无论它们是否编码



我想从XML文件中删除表情符号。 典型的示例字符串可以是这样的:

<a>🤬 grêve &#55357;&#56628; SNCF 🔴 ➡️</a>

我只想拥有:

<a>grêve SNCF</a>

我尝试在解析阶段后使用 Nokogiri 的noent选项和一些过滤器,但to_xml将表情符号作为 HTML 实体返回,我不再检测到它们。 它返回如下内容:

<a>&#x1F92C; gr&#xEA;ve  SNCF &#x1F534; &#x27A1;&#xFE0F;</a>
require 'nokogiri'
xml = Nokogiri::XML(%{
<root>
<aliens>
<alien>
<name>
🤬 grêve &#55357;&#56628; SNCF 🔴 ➡️
</name>
</alien>
</aliens>
</root>
}) do |config|
config.noent
end
puts xml
# emoticons
clean_xml_str = xml.to_xml
.unpack('U*')
.reject{ |e|
# emoticons block
e.between?(0x1F600, 0x1F6FF)  ||
# basic block - control characters
e.between?(0x0000, 0x001F) ||
# Private Use Area
e.between?(0xE000, 0xF8FF)
}
.pack('U*')
puts clean_xml_str

有关详细信息,请参阅 repl.it 上的沙盒。

你要求Nokogiri做一些不是它真正工作的事情。Nokogiri 应该解析有效的 XML,这些字符似乎是有效的。在这些情况下,我们被迫预处理文件,然后将其移交。同样的事情发生在病理损坏的XML或HTML上;这很肮脏,我们觉得这样做很肮脏,但这完全可以接受,而不是事后跳过箍。

在将 XML 传递给 Nokogiri 之前,我会使用一种模式或一对模式来删除正常 ASCII 范围之外的任何字符,或者您认为可接受的任何范围。对于一个快速而肮脏的例子,这会删除 ASCII 范围之外的任何内容,但您需要对其进行微调,因为它正在修改ê

'<a>🤬 grêve &#55357;&#56628; SNCF 🔴 ➡️</a>'.gsub(/[^x20-x7e]+/, '')
# => "<a> grve &#55357;&#56628; SNCF  </a>"

或:

'<a>🤬 grêve &#55357;&#56628; SNCF 🔴 ➡️</a>'.gsub(/[^[:ascii:]]+/, '')
# => "<a> grve &#55357;&#56628; SNCF  </a>"

只需将编码的字符串添加到模式中,或运行第二次传递来处理它们。Ruby的正则表达式文档将帮助您对其进行微调。

至于"如何从字符串中删除表情符号"中的解决方案,它也可以工作,但它会更慢,因为它会遍历每个字符。 带有模式gsub会将其传递给 Ruby 的正则表达式引擎,如果您将其传递给整个 XML 文件,该引擎的运行速度会快得多。

最新更新