【问题标题】:Using Regular Expressions in Xpath in R在 R 的 Xpath 中使用正则表达式
【发布时间】:2015-08-13 12:28:04
【问题描述】:

我正在尝试使用 R 匹配一组 XML 节点。这些节点的结构是名称#。我知道这可以很容易地与正则表达式匹配,但我似乎无法让它在 R 中工作。这是一个示例。

我要匹配的节点:

<matrix4>...</matrix>
<matrix5>...</matrix>
<matrix2>...</matrix>

我正在使用 XML 包访问节点:

library("XML")
...
getNodeSet(head_node, ".//matrix2|.//matrix4|.//matrix5")

我一直在尝试使用匹配功能,但我似乎可以让它工作。我不确定 R 是否支持匹配。任何帮助将不胜感激。

【问题讨论】:

  • XPath 1.0 不支持正则表达式,XML/xml2 只支持 XPath 1.0
  • 感谢您告诉我,这很不幸。有没有我可以使用的支持正则表达式的类似包?
  • 您还可以使用路径字符串向量,例如getNodeSet(doc, paste0("//matrix", c(2,4,5)))

标签: regex xml r xpath


【解决方案1】:

如前所述,您不能使用正则表达式,但可以生成不同的路径字符串。

doc <- xmlParse("<set>
  <matrixA>...</matrixA>
  <matrix2>...</matrix2>
  <matrixC>...</matrixC>
  <matrix421>...</matrix421>
  <matrix55>...</matrix55>
</set>")

#exact numbers matching matrix2, 4 or 5
getNodeSet(doc, paste0("//matrix", c(2,4,5)))
[[1]]
<matrix2>...</matrix2> 

#matching ANY Number
getNodeSet(doc, paste0("//*[starts-with(name(), 'matrix", 0:9, "')]"))
[[1]]
<matrix2>...</matrix2> 
[[2]]
<matrix421>...</matrix421> 
[[3]]
<matrix55>...</matrix55> 

# or maybe use a regular expression on the names and then index
n <-grep("matrix[0-9]", xpathSApply(doc, "//set/*", xmlName))
getNodeSet(doc, "//set/*")[n]

【讨论】:

    【解决方案2】:

    这里有几种不用正则表达式的方法:

    # with XML ----------------------------------------------------------------
    
    library(XML)
    
    doc <- xmlParse("<set>
    <matrix4>...</matrix4>
    <matrix5>...</matrix5>
    <matrix2>...</matrix2>
    </set>")
    
    # a bit generic (i.e. useless if you need to only choose certain "matrix" tags)
    getNodeSet(doc, "//*[starts-with(name(), 'matrix')]")
    
    ## [[1]]
    ## <matrix4>...</matrix4> 
    ## 
    ## [[2]]
    ## <matrix5>...</matrix5> 
    ## 
    ## [[3]]
    ## <matrix2>...</matrix2> 
    ## 
    ## attr(,"class")
    ## [1] "XMLNodeSet"
    
    # closer to what you need
    getNodeSet(doc, "//*[name()='matrix4' or name()='matrix2']")
    ## [[1]]
    ## <matrix4>...</matrix4> 
    ## 
    ## [[2]]
    ## <matrix2>...</matrix2> 
    ## 
    ## attr(,"class")
    ## [1] "XMLNodeSet"
    
    # with xml2 ---------------------------------------------------------------
    
    library(xml2)
    
    doc <- read_xml("<set>
    <matrix4>...</matrix4>
    <matrix5>...</matrix5>
    <matrix2>...</matrix2>
    </set>")
    
    # a bit generic (i.e. useless if you need to only choose certain "matrix" tags)
    xml_find_all(doc, "//*[starts-with(name(), 'matrix')]")
    ## {xml_nodeset (3)}
    ## [1] <matrix4>...</matrix4>
    ## [2] <matrix5>...</matrix5>
    ## [3] <matrix2>...</matrix2>
    
    # closer to what you need    
    xml_find_all(doc, "//*[name()='matrix4' or name()='matrix2']")
    ## {xml_nodeset (2)}
    ## [1] <matrix4>...</matrix4>
    ## [2] <matrix2>...</matrix2>
    

    【讨论】:

    • 第二种方法不是和我已经在做的一样吗?第一种方法更接近我想要的,但我只想匹配矩阵后跟一个数字,有时节点以矩阵开头,后面跟着其他东西。
    猜你喜欢
    • 2020-11-21
    • 1970-01-01
    • 2010-09-29
    • 2011-05-02
    • 2022-01-11
    • 1970-01-01
    • 2015-04-08
    • 2020-08-15
    • 2011-02-14
    相关资源
    最近更新 更多