0

我有一个字符串,我需要在其上进行正则表达式匹配(我在 R 中工作)。看起来像:

"354542676655341568:1373344735:270969722:text1,text2,text4,text8"

该字符串有 4 个部分,由分号 ( :) 分隔。我有多个具有不同值的字符串,但由相同的 4 个部分组成。我计划使用匹配的第一个数字部分"[0-9]{18}" 对于第二部分(它是时间戳),我有一段代码为我将附加的范围生成正则表达式。示例如下所示:

":0*13733([0-3][0-9]{4}|4([0-3][0-9]{3}|4([0-7][0-9]{2}|800))):"

上述模式匹配 1373300000 和 1373344800 之间的所有数字。第三部分也是一个普通的[0-9]{9}

问题是第四部分,我必须匹配文本部分。我将有一个文本内容列表,如text1, text3, text5。如果它具有列表中的至少一个文本,我需要接受该字符串。它更像是第四部分的子字符串匹配。

我曾想过拆分文本,但在我的应用程序中,这将是一个糟糕的设计,而且资源成本很高。因此,我想生成一个可以一起完成整个匹配的正则表达式。

我尝试了一些方法来测试这一点,但我得到了误报。有什么可用的帮助吗?

checktext = "check:text1,text2,text3"
> grepl("check:[a-zA-Z0-9 ]+,text2",checktext)
[1] TRUE
> grepl("check:[a-zA-Z0-9, ]+,text2",checktext)
[1] TRUE
> grepl("check:[a-zA-Z0-9, ]+,[text3|text2]",checktext)
[1] TRUE
> grepl("check:[a-zA-Z0-9, ]+,[text3|text4]",checktext)
[1] TRUE
> grepl("check:[a-zA-Z0-9, ]+,[text5|text4]",checktext)
[1] TRUE
> grepl("check:[a-zA-Z0-9, ]+,[text5|text4][a-zA-Z0-9, ]$",checktext)
[1] FALSE
> grepl("check:[a-zA-Z0-9, ]+,[text5|text3][a-zA-Z0-9, ]$",checktext)
[1] FALSE
> grepl("check:[a-zA-Z0-9, ]+,[text5|text3][a-zA-Z0-9, ]+?$",checktext)
[1] TRUE
> grepl("check:[a-zA-Z0-9, ]+,[text5|text4][a-zA-Z0-9, ]+?$",checktext)
[1] TRUE
> grepl("check:.*[text1].*",checktext)
[1] TRUE
> grepl("check:.*[text2].*",checktext)
[1] TRUE
> grepl("check:.*[text3].*",checktext)
[1] TRUE
> grepl("check:.*[text2|text4].*",checktext)
[1] TRUE
> grepl("check:.*[text5|text4].*",checktext)

在@sgibb 的回复之后,我将所有部分放在一起以制作最终模式:

"[0-9]{18}:0*13733([0-3][0-9]{4}|4([0-3][0-9]{3}|4([0-7][0-9]{2}|800))):[0-9]{9}:[a-zA-Z0-9, ]+,(Samsung|Nokia)"

我的文本字符串是:

"354542676655341568:1373344735:270969722:Samsung,Galaxy"

它不匹配。是因为把它们都放在一起吗?当我从正则表达式中删除最后一个(文本)部分时,它匹配了。

> finalpattern
[1] "[0-9]{18}:0*13733([0-3][0-9]{4}|4([0-3][0-9]{3}|4([0-7][0-9]{2}|800))):[0-9]{9}:"

> keysample
    [1] "354542676655341568:1373344735:270969722:Samsung,Galaxy"
    > grepl(finalpattern,keysample)
    [1] TRUE
4

1 回答 1

3

恕我直言,您使用[错误。A[包含要匹配的一类字符(意味着至少有一个字符应该[匹配)。如果要对模式/字符串(例如text5|text4)进行分组,则必须使用(

grepl("check:[a-zA-Z0-9, ]+,(text3|text4)",checktext)
# [1] TRUE
grepl("check:[a-zA-Z0-9, ]+,(text5|text4)",checktext)
# [1] FALSE

这应该可以消除大部分误报。

解决您的编辑:

你的正则表达式是错误的(后面的部分:)。

[a-zA-Z0-9, ]+,:您寻找字母数字字符(顺便说一句,请参阅?regex: classes [:alnum:])至少出现一个,然后是,. 这将再次匹配Samsung

接下来你寻找(Samsung|Nokia)但只剩Galaxy下了。

有多种解决方案:

"[[:alnum:], ]*(Samsung|Nokia)[[:alnum:], ]*"

"(Samsung|Nokia),[[:alnum:], ]+"

".*(Samsung|Nokia).*"

# ...

或者您应该考虑拆分字符串:并分别分析每个部分。

于 2013-07-10T07:59:03.010 回答