使用 Grep 和/或 RegEx 从 R 中的元数据字段中提取 ID 的模式匹配

Pattern Matching using Grep and/or RegEx to Extract ID from metadata field in R

提问人:Hack-R 提问时间:8/7/2014 最后编辑:oguz ismailHack-R 更新时间:8/10/2020 访问量:794

问:

我有如下所示的元数据字符串:

{\"vote\":\"com.jivesoftware.community.acclaim.impl.VoteImpl@8b6b31f7\",\"referringSource\":null,\"referringUser\":null,\"acclaim\":\"AcclaimImpl{acclaimID=3146, object=EntityDescriptor{objectID=1900, objectType=102}, acclaimType='like', visibility=true, creationDate=Mon Jul 13 11:52:18 PDT 2014, modificationDate=Mon Jul 13 11:52:18 PDT 2014, properties={}}\",\"create\":true} 

我需要提取.我一直在尝试使用模式匹配,但我不断得到objectID

  1. 没有匹配项
  2. 返回给我的整个元数据,或者
  3. 意想不到的结果

例如,我为一个简单的测试创建了这个对象:

testme <- "{\"vote\":\"com.jivesoftware.community.acclaim.impl.VoteImpl@8b6b31f7\",\"referringSource\":null,\"referringUser\":null,\"acclaim\":\"AcclaimImpl{acclaimID=3246, object=EntityDescriptor{objectID=1400, objectType=102}, acclaimType='like', visibility=true, creationDate=Mon Jul 14 11:52:18 PDT 2014, modificationDate=Mon Jul 14 11:52:18 PDT 2014, properties={}}\",\"create\":true}"

我尝试以下操作,当我在一个名为 的程序中创建和测试它时,它似乎可以正常工作,并在该程序中指定了我的 R 版本:RegEx Magic

grep("\\AobjectID=[0-9]+[[:>:]]\\z", testme, perl=TRUE, value=TRUE);

然而我得到的结果是:

character(0)

我尝试了一些更简单的方法,例如:

regexpr(pattern="\\<objectID=[0-9]{1,4}", testme, useBytes = FALSE, fixed = TRUE)

regexpr(pattern="\\bobjectID=[0-9]", testme, useBytes = FALSE)

这些导致了意想不到的结果(即我不确定它给了我什么,但这不是我想要的):

[1] -1
attr(,"match.length")
[1] -1
attr(,"useBytes")
[1] TRUE

[1] 176
attr(,"match.length")
[1] 10
attr(,"useBytes")
[1] TRUE

分别。如果我删除 or,那么它会返回整个元数据字符串。\\b\\<

有人可以帮我解决这个问题吗?提前致谢。

r 正则表达式

评论

0赞 Casimir et Hippolyte 8/7/2014
由于是字符串开头和结尾的锚点,因此您没有获得结果是正常的,因为您要查找的内容位于字符串的中间。当你使用时,你可以忘记这种旧的 POSIX/SQL 边界:,请改用。\A\zperl = TRUE[[:>:]]\b
0赞 Hack-R 8/7/2014
明白了。谢谢。那么,我得到的奇怪结果是什么?\b
0赞 Casimir et Hippolyte 8/7/2014
\b是与类的成员与非成员字符之间或非成员与字符类的成员之间的位置匹配的单词边界。对于您的情况,您只需要在开头使用它(因为您正在寻找一个字母 (O) 前面没有其他字母),并且因为数字 (member) 后面跟着逗号(非成员)。在 R 语言中,您必须编写(无需在末尾放置边界,因为量词是贪婪的(换句话说,您将获得所有可能的数字))。\w\w\\bObjectID=\\d++

答:

1赞 rsoren 8/7/2014 #1

您可以找到 和 的位置,然后选择相对于这些位置的数据。objectIDobjectType

require(stringr)
objectID_loc <- str_locate(x, "objectID")
objectType_loc <- str_locate(x, "objectType")
objectID <- substr(x, objectID_loc[, "end"] + 2, objectType_loc[, "start"] - 3)

这为您提供了:

> objectID
[1] "1900"

评论

0赞 Hack-R 8/7/2014
谢谢。我选择了第一个正确的响应,但这也有效。我给你投了赞成票。
0赞 rsoren 8/7/2014
从技术上讲,我比他快了几秒钟。唉!;D很高兴你找到了有效的东西
0赞 Hack-R 8/7/2014
谢谢。对不起,如果你先回答,我的错误!
1赞 G. Grothendieck 8/7/2014 #2

使用第一个示例字符串尝试此操作。它与正则表达式匹配,并返回括号内的部分:

> library(gsubfn)
> strapplyc(s, "objectID=(\\d+)")[[1]]
[1] "1900"
2赞 hwnd 8/7/2014 #3

需要明确的是,你得到结果的原因是你的正则表达式不正确。锚点与字符串开头的位置匹配,锚点与字符串末尾的位置匹配。character(0)\A\z

您要搜索的子字符串在字符串中既不位于位置,实际上也不在中间位置。因此,您需要删除锚点,也可以删除与字符类相关的边界。perl=T

> grep("objectID=[0-9]+", x, value=TRUE)
# [1] "{\"vote\":\"com.jivesoftware.community.acclaim.impl.VoteImpl@8b6b31f7\",\"referringSource\":null,\"referringUser\":null,\"acclaim\":\"AcclaimImpl{acclaimID=3246, object=EntityDescriptor{objectID=1900, objectType=102}, acclaimType='like', visibility=true, creationDate=Mon Jul 14 11:52:18 PDT 2014, modificationDate=Mon Jul 14 11:52:18 PDT 2014, properties={}}\",\"create\":true}"

注意:返回包含所选元素的字符向量。grep(value = TRUE)

如果要获取子字符串值,基本 R 可以很好地处理此问题。

> regmatches(x, gregexpr('(?<=\\bobjectID=)\\d+', x, perl=T))[[1]]
# [1] "1900"

或者你可以简单地使用库来做到这一点。stringr

> library(stringr)
> str_extract(x, perl('(?<=\\bobjectID=)\\d+'))
# [1] "1900"

评论

0赞 Hack-R 8/8/2014
谢谢。这非常有帮助,你显然是对的。我不得不问——为什么它在我的 RegEx 应用程序中有效(我使用了 RegEx Magic/Buddy,有人试图在 Freenode 的 #regex 中帮助我,并通过另一个验证器想出了类似的东西)?无论如何,再次感谢;谁知道那个应用程序是怎么回事。