提取基于字符串的一部分-R

时间:2019-06-12 09:00:18

标签: r

HI在df以下,我需要根据字符数提取其中的一部分。

在text1列中,我只需要ID 16的数字16593和ID 2的10227。

期望的结果是:

    id text1
    1  16593 
    2  10227 

所需的数字始终在该字符串"no_i</name><primaryKey>true</primaryKey><newValue>16593"中,因此我尝试从no_i单词中提取基于45个字符的数字,并且结尾是

谁知道我该怎么办?

我的df在下面。

 id <- c(1,2)
text1 <- c( 
  "<?xml version=1.0 encoding=UTF-8 standalone=yes?><businessObjectChanges version=1><table><datetime>1556122543608</datetime><name>header</name><row><datetime>1556122543608</datetime><transactionType>UPDATE</transactionType><column><name>status</name><newValue>14</newValue><oldValue>13</oldValue><mimeType>INT</mimeType></column><column><name>no_i</name><primaryKey>true</primaryKey><newValue>16593</newValue><oldValue>16593</oldValue></column></row></table></businessObjectChanges>",
  "<?xml version=1.0 encoding=UTF-8 standalone=yes?><businessObjectChanges version=1><table><datetime>1547028713373</datetime><name>header</name><row><datetime>1547028713373</datetime><transactionType>UPDATE</transactionType><column><name>status</name><newValue>14</newValue><oldValue>13</oldValue><mimeType>INT</mimeType></column><column><name>no_i</name><primaryKey>true</primaryKey><newValue>10227</newValue><oldValue>10227</oldValue></column></row></table></businessObjectChanges>"

)
    my_text <- data.frame (id, text1) 

4 个答案:

答案 0 :(得分:1)

您可以尝试

my_text$text1 = gsub(".*>(.*)","\\1",my_text$text1)

> my_text
  id text1
1  1 16593
2  2  1022

regex基本上会查找任何内容(.*),直到最后一次出现>为止,而仅保留下一个(即您的数字)。
替代

或者,您可以使用

gsub(".*<newValue>(\\d+)<\\/newValue>.*","\\1",my_text$text1)  

如果您的数字始终放在<newValue>之间。

答案 1 :(得分:0)

按照您的建议,我们可以使用sub提取my_text$num <- sub(".*no_i</name><primaryKey>true</primaryKey><newValue>(\\d+).*", "\\1", my_text$text1) my_text[c(1, 3)] # id num #1 1 16593 #2 2 10227 之后的数字。

body {
    --src-image: url("some image");
}

.btn {
    background-image: var(--src-image);
}

.btn:hover {
    opacity: 0.7;
}

答案 2 :(得分:0)

如果您的电话号码始终为5位数字,则以下内容可能会有所帮助。如果要输入5位和6位数字,则可以更改为{5,6}。

library(tidyverse)
my_text %>% 
  mutate(text1 = str_extract(text1, "\\b\\d{5}\\b"))

答案 3 :(得分:0)

您有XML,但是您以损坏的形式表示了XML,并且您尝试使用正则表达式而不是“ xpath”查询。重新设置原始XML,例如,在第一行中的版本/编码/独立引用和第二行中的版本引用为

txt = '
    '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     <businessObjectChanges version="1">
       <table><datetime>1556122543608</datetime><name>header</name>
       <row>
         <datetime>1556122543608</datetime><transactionType>UPDATE</transactionType>
         <column><name>status</name><newValue>14</newValue><oldValue>13</oldValue><mimeType>INT</mimeType></column>
         <column><name>no_i</name><primaryKey>true</primaryKey><newValue>16593</newValue><oldValue>16593</oldValue></column>
       </row></table>
     </businessObjectChanges>'

并使用xpath语言提取所需的字段

library(xml2)
xml = read_xml(txt)
xpath = "number(//name[text()='no_i']/following-sibling::newValue)"
xml_find_first(xml, xpath)

xpath有点高级。 number()将包含在表达式中的值强制转换为数字。 //name[text()='no_i']标识了从文档到文本等于name的节点'no_i'的路径。 following-sibling::newValue查找名为name的同级节点(与刚刚确定的newValue节点处于同一嵌套级别);

> xml_path(xml_find_first(xml, "//name[text()='no_i']/following-sibling::newValue/text()"))
[1] "/businessObjectChanges/table/row/column[2]/newValue/text()"

一个不同,更简单,同样有效的xpath可能是

number(//primaryKey/../newValue)

想法是写一个在单个xml文档上执行此功能的函数

find_new_value <- function(txt, xpath) {
    xml = read_xml(txt)
    xml_find_first(xml, xpath)
}

并将其应用于您的(更正后的)XML文本的每个元素

xpath = "number(//primaryKey/../newValue)"
sapply(my_text$text1, find_new_value, xpath)

或在dplyr-land

my_text %>% mutate(value = find_new_value(text1, xpath))