以下模式:来自http://regexr.com/的(v[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2})(-[0-9]{1,2})?((-schema)?(-dev)?)((-schema)?(-dev)?)
旨在用于grep
的shell脚本,并且与以下字符串匹配(工作示例):
Hello I am a text and this is my v1.12.33-32 version
Hello I am a text and this is my v1.12.33-dev version
Hello I am a text and this is my v1.12.33-dev-schema version
Hello I am a text and this is my v1.12.33-schema version
Hello I am a text and this is my v1.12.33-3-schema version
等等
所以我将单词schema
和dev
设为可选。可以以任意顺序省略或使用它们。我不是这样的:
Hello I am a text and this is my v1.12.33-foo version
或Hello I am a text and this is my v1.12.33-asfs version
匹配。
我希望选项更加受限制。目前,正则表达式仍然匹配......实际匹配的东西。
例如:
Hello I am a text and this is my v1.123.33
会产生空字符串,而这是:
`你好我是一个文本,这是我的v1.12.33-bla“
仍会导致v.1.12.33
这是因为我制作的分组吗?那么至少完全匹配的组将被用于返回的匹配字符串?
答案 0 :(得分:1)
由于正则表达式是开放式的,因此您需要使用$
指定匹配结束的位置,因此您不要让正则表达式引擎静默忽略尾随垃圾。
在可选集中只有两个标签,我只想列举4种可能性:
(v[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2})(-[0-9]{1,2})?(-schema|-dev|-dev-schema|-schema-dev)?$
答案 1 :(得分:1)
问题似乎是潜伏在所有的可选表达 边缘(结束)。
你可以通过几种方式解决这个问题,但是因为你需要,所以没有一种方法可以解决这个问题
更多规则来控制匹配的内容
它不像你可以说不允许-
后记,引擎将为
回溯到其中一个范围数字{1,2}
以进行匹配。
现在似乎工作的是传递空白端边缘 或匹配 dev / schema 项目。
(v[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2})(-[0-9]{1,2})?(?:(?!\S)|(-(schema|dev)(?:-(schema|dev))?))
扩展
( # (1 start)
v [0-9]{1,2}
\. [0-9]{1,2}
\. [0-9]{1,2}
) # (1 end)
( - [0-9]{1,2} )? # (2)
(?:
(?! \S ) # Whitespace boundary
| # or,
( # (3 start)
-
( schema | dev ) # (4)
(?:
-
( schema | dev ) # (5)
)?
) # (3 end)
)
编辑
如果要避免两次匹配相同的架构| dev 字,只需添加
在上面的捕获组5之前,对组4的否定断言。
(v[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2})(-[0-9]{1,2})?(?:(?!\S)|(-(schema|dev)(?:-(?!\4)(schema|dev))?))
扩展
( # (1 start)
v [0-9]{1,2}
\. [0-9]{1,2}
\. [0-9]{1,2}
) # (1 end)
( - [0-9]{1,2} )? # (2)
(?:
(?! \S ) # Whitespace boundary
| # or,
( # (3 start)
-
( schema | dev ) # (4)
(?:
-
(?! \4 ) # Not same word twice
( schema | dev ) # (5)
)?
) # (3 end)
)
答案 2 :(得分:1)
我的版本:
\b
其中
(?: ... )
是一个单词边界(你可能想让它更严格); \s|$
表达式为redirect output; schema
可以是空格字符,也可以是行尾其余的只是为了简单而重构。
表达式只允许在{"结束" dev
或order by
。
答案 3 :(得分:1)
要仅匹配 版本字符串,禁止使用额外的尾随标记,但允许尾随不匹配的文本,则需要支持前瞻的正则表达式语言。标准grep
/ egrep
正则表达式不支持预测。
您有两种选择:
grep
,你可以使用Perl正则表达式,例如v[0-9]{1,2}(\.[0-9]{1,2}){2}(-[0-9]{1,2})?((-schema(-dev)?)?|(-dev(-schema)?)?)?(?!\S)
最后的否定前瞻允许匹配出现在行的末尾,但也要求如果它不结束行,那么匹配后的下一个字符必须是空格(它本身不包括在内)匹配)。
-o
完全隔离目标文本,而是允许模式匹配尾随上下文:v[0-9]{1,2}(\.[0-9]{1,2}){2}(-[0-9]{1,2})?((-schema(-dev)?)?|(-dev(-schema)?)?)?(\s.*)?$
在这种情况下,您可以通过剥离以空格开头的任何尾部来在第二步中隔离目标文本。
请注意,这些都不会引起之前匹配的文字。您可以像处理尾随部分一样处理该部分。