【问题标题】:How can I split a string in perl, keeping the delimiters, and having the split be between the delimiters?如何在 perl 中拆分字符串,保留分隔符,并在分隔符之间进行拆分?
【发布时间】:2012-04-13 04:59:46
【问题描述】:

我的问题有点罗嗦,所以我会尝试用一个例子来解释。

我有一个文件有点类似于我需要解析的 XML,虽然不完全一样。文件中的元素通常显示类似于 XML 格式,如

<person><greeting>hello</greeting><goodbye>bye</goodbye></person>

我想把文件分成单独的标签集,这样一个元素就可以了

<greeting>hello</greeting>

另一个是

<goodbye>bye</goodbye>

对于一个空元素,&lt;person&gt;&lt;/person&gt; 自然会成为它们自己的元素,我完全可以接受,因为我想将文件作为一个整体进行解析。

我遇到的问题是如何最好地将整个文件拆分为一个数组,因为文件中根本没有换行符,它是如你所见那样写出来的。我试过这样做

my @array = split(/(><)/, $file)

但问题是它不会将尖括号保留为关联标签的一部分,而是将它们分开。有没有办法让我将文件 > 和

【问题讨论】:

  • 如果您的文件与 XML 足够接近,为什么不直接使用 XML 解析器?
  • 基本上这是家庭作业,或者足够接近它。这是一个正则表达式的练习,而不是 XML 解析,我们被鼓励不要使用 XML 库。

标签: xml regex perl split


【解决方案1】:

我不确定这是否是最佳解决方案,但要直接回答您的问题,您可以使用 lookbehind and lookahead assertions 在角度之间进行拆分。

my @array = split(/(?<=>)(?=<)/, $file)

不同的是。他们不消耗&gt;&lt; 部分,他们匹配两者之间的位置。

另一个想法是使用反向引用来匹配正确的(它匹配具有此名称的第一个结束标签,当嵌套相同的标签时这是错误的)结束标签,像这样

<([^>]*)>(.*?)</\1>

here on Regexr

你在这个正则表达式中有两个引用。第一个用来匹配结束标签,第二个你会找到标签的内容。

当然它首先会匹配“person”标签,但你会在$2中找到其他标签。您必须在 $2 上递归使用正则表达式,直到结果为空数组。

【讨论】:

  • 这似乎工作得几乎完美,但似乎在每个完整元素之间插入了空元素。
  • @DanielSarder 正则表达式周围的(不需要)捕获组导致数组中的元素为空。更正了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-26
  • 2022-11-03
  • 2017-07-24
  • 2011-04-16
  • 2011-01-09
相关资源
最近更新 更多