我有一些字符串来搜索与正则表达式的匹配。
foo
AB0001
AB0002 foo
foo AB0003
foo AB0004A AB0004.1
AB0005.1 foo AB0005A bar AB0005
所需的匹配是每行一个ID,而末尾带有字母的ID应该优先,而带有.1的ID应该被忽略。
foo -> no match
AB0001 -> AB0001
AB0002 foo -> AB0002
foo AB0003.1 -> no match
foo AB0004A AB0004.1 -> AB0004A
AB0005.1 foo AB0005A bar AB0005 -> AB0005A
我认为我可以轻松地使用交替|
符号给出的优先级来在最后用大写字母对ID进行优先级排序,但是总是会给出多个匹配项。
我的建议: regex101.com/r/yP5kX4/1
Offtopic:何时使用以^
开头的整个RegEx以$
结尾并使用捕获/非捕获组,何时应尽可能缩短RegEx?
答案 0 :(得分:1)
这是一种方式。它有点复杂,因为你需要懒得找到 ID的第一个实例。
此正则表达式将用于多行模式。在开头添加(?m)
正如你所知的正则表达式
结果ID位于捕获组1中。
^.*?\b([A-Z]+\d+[A-Z]|[A-Z]+\d+(?!\.\d)(?!.*?\b[A-Z]+\d+[A-Z]))\b
解释
^ # Beginning of string
.*? # Any char, lazy to get first instance
\b
( # (1 start), the ID
[A-Z]+ \d+ [A-Z] # Priority, with trailing letter
| # or,
[A-Z]+ \d+ # no trailing letter
(?! \. \d ) # no dot digit after digit
(?! .*? \b [A-Z]+ \d+ [A-Z] ) # and only if not a trailing letter id downstream
) # (1 end)
\b
答案 1 :(得分:0)
我想以这种方式检测 R 3.1.3 中的字符串:
grepl("(?<!\\.)[A-Z0-9]+?(?=\\s)", subject, perl=TRUE);
根据您在问题中发布的输入,输出将为:
<强> INPUT 强>
foo AB0001 AB0002 foo foo AB0003 foo AB0004A AB0004.1 AB0005.1 foo AB0005A bar AB0005
-
<强>输出强>
答案 2 :(得分:0)
以下正则表达式应该:
(AB(?:[0-9A-Z]{5}|[0-9]{4}))(?:\s+)
我在ID匹配后添加了一个非捕获组(?:\ s +)来捕获空间。 演示是HERE:
我的想法:(如果我错了,请纠正我)
何时使用以$结尾的整个RegEx? 如果正则表达式匹配整个字符串的开始(^)到结束($)。
使用捕获/非捕获组? 如果要提取/引用该信息,请使用捕获组; 如果您只想匹配,则使用非捕获组,但不提取和引用。请查看:What is a non-capturing group? What does a question mark followed by a colon (?:) mean?。
我应该何时尽可能缩短RegEx? 越短越好,只要它起作用
答案 3 :(得分:0)
\b(AB\d{4}(?!\.\d)[A-Z]?)\b
那是AB
后跟四位数字,后面不能跟一个十进制数字序列,但可能以一个字母结尾。单词边界(\b
)有助于确保匹配的序列不是像
基于交替的解决方案永远不会起作用。确实,如果交替的两个或多个分支可以在给定点匹配 ,则始终选择第一个分支(无论如何,大多数正则表达式都是如此)。但这对你没有帮助,因为正则表达式引擎始终支持第一个(最左边)匹配;这是它的最高优先级。所以第一场比赛无论胜利的哪个分支都会胜出。
对于锚点(^
和$
),它们通常只在你想要匹配整个字符串时才需要,或者在多线模式下匹配整行(和BTW,因为你'不使用它们,你不需要/m
标志;它所做的就是改变锚点的含义。)
捕捉群组的问题在这里很有趣,因为你不需要它们。我使用它的唯一原因是因为Regex101网站没有在侧面板中显示匹配,除非它们在捕获组中。在一个非常有用的网站上,这是一个恼人的小故障。但一般来说,当您需要提取匹配的特定部分时,或者需要在正则表达式中使用反向引用时,可以使用捕获组。