我有一个字符串,我需要在其上进行正则表达式匹配(我在R中工作)。它看起来像:
"354542676655341568:1373344735:270969722:text1,text2,text4,text8"
此字符串由colens(:
)分隔的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
答案 0 :(得分:3)
恕我直言,你使用[
错误。 [
包含要匹配的字符类(意味着 [
中的至少一个字符应该匹配)。如果要对模式/字符串进行分组(例如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, ]+,
:您要查找至少出现的字母数字字符(BTW,请参阅?regex
:类[:alnum:]
),然后是,
。这将再次匹配Samsung
。
接下来,您要查找(Samsung|Nokia)
,但只剩下Galaxy
。
有多种解决方案:
"[[:alnum:], ]*(Samsung|Nokia)[[:alnum:], ]*"
"(Samsung|Nokia),[[:alnum:], ]+"
".*(Samsung|Nokia).*"
# ...
或者您应该考虑将字符串拆分为:
并分别对每个部分进行分析。