正则表达式:计数连续出现xquery

时间:2012-10-25 11:14:33

标签: xml regex xquery

我有一系列像这样的xml元素: <addr>via roma</addr> <addr>via milano</addr> <addr>via napoli</addr> ...

我想检查是否有一个包含相同连续地址3次或更多次的地址序列,例如: <addr> via napoli</addr> <addr>via roma</addr> <addr>via roma</addr> <addr>via roma</addr> <addr>via milano</addr> ....

xml元素的输入序列是xquery的结果。我想我应该使用fn:matches()函数,但我不能编写与此序列匹配的正则表达式。

3 个答案:

答案 0 :(得分:2)

不需要正则表达式。如果$addrs是一系列addr元素,那么

for $a at $i in $addrs
  let $text := string($a)
  where string($addrs[($i + 1)]) eq $text and string($addrs[($i + 2)]) eq $text
  return ($i, $a)

$addrs提供元素和索引,其中三个相等连续地址的子序列开始,在本例中为(2, <addr>via roma</addr>)

请注意,$addrs中存在长度> 4的子序列时,您将获得重复的地址。

答案 1 :(得分:2)

当序列true()包含$ n或更多具有相同字符串值的连续项时,此查询(和Xpath 3.0表达式)产生$seq

    boolean($seq
              [some $i in 1 to count($seq) -($n -1)
                 satisfies
                    not(distinct-values(subsequence($seq, $i, $n))[2])
              ]
             )

因此,在此特定情况下

let $n := 3,
    $seq := /*/addr
 return
        boolean($seq
                  [some $i in 1 to count($seq) -($n -1)
                     satisfies
                        not(distinct-values(subsequence($seq, $i, $n))[2])
                  ]
                 )

生成

true

答案 2 :(得分:1)

使用正则表达式

<addr>([^<>]*)<\/addr>\s*<addr>\1<\/addr>\s*<addr>\1<\/addr>