Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 使用Perl和正则表达式,如何删除字符串中的字符串?_Regex_Xml_Perl - Fatal编程技术网

Regex 使用Perl和正则表达式,如何删除字符串中的字符串?

Regex 使用Perl和正则表达式,如何删除字符串中的字符串?,regex,xml,perl,Regex,Xml,Perl,因此,我有几个XML文件,其中包含具有唯一ID的人,每个人都有自己喜欢的食物(一个人可以在几个XML文件中): 有些情况下,id=300的人可能在标签的开头就有食物 <person id="299"> <food> <type> Hot Dog </type> </food> </person> <person id="300"> &l

因此,我有几个XML文件,其中包含具有唯一ID的人,每个人都有自己喜欢的食物(一个人可以在几个XML文件中):

有些情况下,id=300的人可能在标签的开头就有食物

<person id="299">
    <food>
       <type> Hot Dog </type>
    </food>
</person>
<person id="300">
    <food>
       <type> Burger</type>
    </food>
</person>

热狗
汉堡
或者在食品标签之前可能还有其他标签

<person id="300">
    <year>
       <birth> 1990 </birth>
       <marriage> 2020 </marriage>
    </year>
    <food>
       <type> Vegan </type>
    </food>
</person>

1990
2020
素食主义者
我需要使用单个Perl正则表达式函数来删除ID为300的人的食物标签,如果它位于person标签的开头、中间或结尾,则需要单独删除

我知道,如果是整个人标签,我可以使用如下内容:

$fileContents =~ s/<person id=\"300\"[^<]+<\/person>//g;

$fileContents=~s/使用替换是不安全的

即使是半途而废的方法也比使用现有的XML解析器复杂

$_->unbindNode()
   for $doc->findnodes('//person[@id="300"]/food');
完整解决方案:

use XML::LibXML qw( );

# my $doc = XML::LibXML->new->parse_file(...);
#    or
# my $doc = XML::LibXML->new->parse_string(...);

$_->unbindNode()
   for $doc->findnodes('//person[@id="300"]/food');

# $doc->toFile(...)
#    or
# $doc->toString(...)
perl-i.bk-pe'BEGIN{undef$/}s.*p=$&$1=~/id=“300”/$p=~s、*?、sr:$p | esg'文件*.xml
…从一个或多个文件*.xml中id=“300”的人员中删除
。保留原始文件,并在文件名中添加
.bk
以重命名原始文件。因此,如果您需要保留原始文件…或将
-i.bk
更改为例如
-i.bk$(日期+%Y%m%d%h%m%S)
,则只运行此操作一次

注:我认为池上的答案要好得多


但有时我们会为不允许额外模块的系统编写perl,而遗憾的是,XML::LibXML并不是一个核心模块。有时,半途而废的XML可能最好/最快地用半途而废的方法处理。也许“XML”是由您无法控制的东西编写的。可能它缺少了人员列表的根节点,如第一个示例中所示(可以用
包围
列表,
使其对XML::LibXML可读),或者用“或”围绕属性值,这对XML::LibXML也不会立即可读。

”我需要使用一个Perl正则表达式函数”--嗯?你为什么要这样做?你能简单解释一下吗?(我想也许你没有意识到有现成的XML库,在各个方面都远远优于手工编写的正则表达式。)你是对的,我应该解释得更好……不是我需要使用它,而是我的代码非常大,所以我想避免使用任何其他库,但似乎我必须这样做。谢谢!明白了;在这种情况下,你需要一个库。使用它很简单,很好,但这是一项有点困难的工作,而且很棘手,你自己做(而且应该不仅仅是一个正则表达式)。工作得很好!非常感谢!Hm
“//person[@id='300']]/food”
应该改为
”//person[@id='300']/食品“
我想,否则将插入
@id
。@KjetilS.修复,谢谢。讽刺的是,我使用了双引号字符串文字,这样他们就可以轻松地插入id,而不是硬编码它。
perl -i.bk -pe'BEGIN{undef$/}s|<person (.*?)>.*?</person>|$p=$&;$1=~/id="300"/?$p=~s,<food>.*?</food>,,sr:$p|esg' files*.xml