4

我使用来自飞机制造商 B 的数据。我需要将此数据提供给第三方,以便他们开发可以操作它的工具。
问题是数据需要匿名,因为我们与 B 签订了保密协议。所以每当我们有类似的元素时

<element>Some really sensitive information</element>  

我们需要将文本内容替换为非敏感内容。我可以用 perl 单行符来做到这一点,以用 * 替换所有字母数字字符。

perl -ne 'if(/<(PARA)>([^<]*)<\/PARA>(.*)/){$tag = $1;$content = $2; $content =~ s/\S/*/g;print "<".$tag.">".$content."</".$tag.">".$3."\n"}else{print $_;}' infile > outfile

但是,因为我想让匿名数据更具可读性,并且相关工具更易于排除故障,所以我想插入“真实”文本而不是 *,需要注意的是条目文本内容需要是相同的长度。单个单词改变长度没有问题,但整体文本内容必须具有相同的长度。

所以结果将是“lorem ipsum”类型的东西。

这样做的一个缺点是我最终会得到所有<title>元素,例如,具有相同的开头,例如<title>Lorem Ipsum</title> & <title>Lorem Ips</title>对于人类读者来说不太容易区分。
所以最终的解决方案是我有一个可用的文本文件,我将从该文本块中的随机起点选择长度正确的文本块。(我在想一个马塞尔普鲁斯特的地方只是为了自命不凡)

如果有人能以 perl 单线的方式做到这一点,我将永远敬畏。
假设目标元素总是在自己的一行上,并且元素只包含文本,没有子元素或属性。

4

1 回答 1

4

好的,这是一个正确的方法,使用 XML 解析器和所有,在一个(非常!)长行中:

perl -MText::Lorem -MXML::Twig -E'$t= Text::Lorem->new; XML::Twig->parse( twig_roots => { PARA => sub { $l= length $_->text; $_->set_text( substr( $t->words( $l), 0, $l)); $_->flush} }, twig_print_outside_roots => 1, keep_spaces => 1, $ARGV[0])' myfile.xml

采用正则表达式:

perl -MText::Lorem -p -E'BEGIN { $t= Text::Lorem->new; } s{<PARA>(.*)</PARA>}{$l=length $1; "<PARA>" . substr( $t->words( $l), 0, $l) . "</PARA>"}eg' myfile.xml

-i如果要就地更改文件,请使用

在这两种情况下,由于 Text::Lorem 不允许指定生成字符串的字符数,我生成一个(更长的)单词字符串,然后取适当长度的子字符串。我怀疑您可以使用$l/2生成的单词数,它仍然可以正常工作。

于 2013-09-25T13:46:39.000 回答