【问题标题】:XPath: Match whole word (using matches function with case insensitive flag)XPath:匹配整个单词(使用不区分大小写标志的匹配函数)
【发布时间】:2012-05-11 07:55:57
【问题描述】:

使用 XPath,我想“匹配整个单词”(用户选项,就像在 VS 搜索中一样)。

似乎containsmatches 函数的工作方式相似,但匹配允许使用i 之类的标志以不区分大小写。

换句话说,我通过这两个 XPath 查询得到了相同的结果:

<pets>
    <dog name="Rupert" color="grey"/>
    <dog name="Ralph" color="brown"/>
    <cat name="Marvin the Cat" color="white"/>
    <cat name="Garfield the Cat" color="orange"/>
    <cat name="Cat" color="grey"/>
    <cat name="Fluffy" color="black"/>
</pets>

Matches XPath: //cat[descendant-or-self::*[@*[matches(.,'Cat')]]]
    returns:
    <cat name="Marvin the Cat" color="white"/>
    <cat name="Garfield the Cat" color="orange"/>
    <cat name="Cat" color="grey"/>


Contains XPath: //cat[descendant-or-self::*[@*[contains(.,'Cat')]]]
    returns:
    <cat name="Marvin the Cat" color="white"/>
    <cat name="Garfield the Cat" color="orange"/>
    <cat name="Cat" color="grey"/>

但我想使用matches 只返回匹配“Cat”整个单词的结果:

<cat name="Cat" color="grey"/>

如何调整匹配查询以匹配整个单词?

编辑: 我忘了说我还需要使用matches函数,因为我需要不区分大小写的标志。

【问题讨论】:

    标签: regex search xpath xpath-2.0


    【解决方案1】:

    这对你有用吗?

    //cat[@*='Cat']
    

    【讨论】:

    • 不是我想要的。我仍然想使用 match 函数,因为我需要不区分大小写...(请参阅上面的编辑)。
    【解决方案2】:

    这个:

    //cat[@*='Cat']
    

    结果:

    <cat name="Cat" color="grey"/>
    

    我使用Xacobeo 进行了验证。

    【讨论】:

    • 不是我想要的。我仍然想使用 match 函数,因为我需要不区分大小写...(请参阅上面的编辑)。
    • @developer 试试这个://cat[translate(@*,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='cat'] 这假设您总是将要匹配的字符串以小写形式传递。
    【解决方案3】:

    使用^$ 字符作为锚点怎么样?

    //cat[descendant-or-self::*[@*[matches(.,'^Cat$')]]]
    

    来自RegEx Syntax in XQuery 1.0 and XPath 2.0

    添加了两个元字符 ^$。默认情况下,元字符 ^ 匹配整个字符串的开头,而 $ 匹配结尾 整个字符串。

    【讨论】:

    • 嗯.. 这给了我想要的结果。但是你能解释一下 ^$ 锚点吗?我以前从未使用过它们..
    • 在答案中添加了链接,请参阅“两个元字符...”部分。
    • 谢谢,我还需要做一些测试,但这似乎可以解决问题!
    • ^$ 匹配行的开始/结束,而不是带有单词边界的子字符串的开始/结束
    【解决方案4】:

    这里有三个相关的函数/运算符。

    matches() 进行正则表达式匹配;您可以使用它来匹配子字符串或通过使用锚点 (^cat$) 来匹配整个字符串,并且您可以设置 'i' 标志以使其不区分大小写。

    contains() 对子字符串进行精确匹配;您可以使用第三个参数(排序规则)来请求不区分大小写的匹配,但指定排序规则的方式取决于您使用的处理器。

    eq 操作符对整个字符串进行精确匹配; “默认排序规则”(在 XPath 的情况下通常使用处理器的 API 设置)可用于请求大小写匹配。这似乎是最接近您的要求的一个,唯一的缺点是指定排序规则比使用带有 match() 的“i”标志更依赖于系统。

    【讨论】:

      【解决方案5】:

      但我想使用匹配来返回匹配“猫”的结果 仅全字:

      <cat name="Cat" color="grey"/>
      

      选择想要的元素有不同的 XPath 表达式

      用途:

      /*/cat[matches(@name, '^cat$', 'i')]
      

      或使用:

      /*/cat[lower-case(@name) eq 'cat']
      

      基于 XSLT 的验证

      <xsl:stylesheet version="2.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:xs="http://www.w3.org/2001/XMLSchema">
       <xsl:output omit-xml-declaration="yes" indent="yes"/>
      
       <xsl:template match="/">
        <xsl:copy-of select=
         "/*/cat[matches(@name, '^cat$', 'i')]"/>
      ======
        <xsl:copy-of select=
         "/*/cat[lower-case(@name) eq 'cat']"/>
      
       </xsl:template>
      </xsl:stylesheet>
      

      应用于提供的 XML 文档时:

      <pets>
          <dog name="Rupert" color="grey"/>
          <dog name="Ralph" color="brown"/>
          <cat name="Marvin the Cat" color="white"/>
          <cat name="Garfield the Cat" color="orange"/>
          <cat name="Cat" color="grey"/>
          <cat name="Fluffy" color="black"/>
      </pets>
      

      此转换评估两个 XPath 表达式并将所选元素复制到输出

        <cat name="Cat" color="grey"/>
      ======
        <cat name="Cat" color="grey"/>
      

      【讨论】:

        猜你喜欢
        • 2022-01-23
        • 2019-01-18
        • 1970-01-01
        • 2014-10-26
        • 1970-01-01
        • 1970-01-01
        • 2017-11-14
        • 2012-03-15
        • 1970-01-01
        相关资源
        最近更新 更多