我需要创建一个 GREP 来搜索文档中的时间戳。但是,这些时间戳在括号中。
例如 (23:54) 或 (02:03) 等等。
括号内的数字各不相同,我需要将它们全部找出来。
这是我过去使用的时间戳:[0-9][0-9]:[0-9][0-9]
但是,这不会选择括号,如果我在此添加括号,它什么也不做。
我也尝试了 /([0-9][0-9]:[0-9][0-9])。但这也不起作用。
有任何想法吗?
另外,有时时间戳是 6 位数字,例如 (02:21:54)。因此,我也需要搜索这些。
答案1
我需要创建一个 GREP 来搜索文档中的时间戳
例如 (23:54) 或 (02:03) 等等。
另外,有时时间戳是 6 位数字,因此 (02:21:54)
使用以下正则表达式:
\([0-9]+:[0-9]+\)|\([0-9]+:[0-9]+:[0-9]+\)
答案2
免责声明
由于我暂时无法对外国问题/答案添加评论,因此我将添加一些补充和背景信息大卫·波斯蒂尔斯通过自己的答案来回答。这是基于我对基于grep
Debian 的 Linux 发行版和衍生产品的知识/经验,因此我无法保证所有内容在其他grep
实现/构建中也同样有效。
背景
括号的问题很可能在于,它们本身就是用于分组模式的扩展正则表达式中的魔法字符,在这种情况下实际上没有任何作用。链接的答案通过反斜杠转义括号来强制按字面解释它们,从而解决了这个问题,因此通常这种方法是可行的。
然而至少在 Debian (Wheezy+) 和 Ubuntu (Xenial+) 中,扩展正则表达式默认不启用grep
。需要通过选项明确启用-E
。根据特定的 grep 默认值,情况可能正好相反,因此可能需要禁用延长正则表达式,而不是通过选项显式地-G
使用。在你的情况下,这将允许你使用你试图捕获括号的正则表达式:
grep -G '([0-9][0-9]:[0-9][0-9])' /path/to/doc
然而,只有基本正则表达式的缺点是|
(alternative1|alternative2
),?
(先前的角色/团体可能存在,也可能不存在)和+
(前一个字符/组出现一次或多次)并且其他一些奇特的东西也丢失了,因此 DavidPostill 的正则表达式的优美之处(允许一个或多个数字并使小时或秒可选)将不再起作用。
但是,可以通过再次使用反斜杠转义来重新启用扩展正则表达式特殊字符。因此,在仅启用基本正则表达式的情况下,DavidPostills 模式在两个方面会受到破坏:
+
并按|
字面意思理解。\(
并被\)
解释为扩展的正则表达式特殊字符来对其封闭的模式进行分组,但在这种情况下实际上没有效果。
解决方案
因此,根据是否grep
将模式解释为基本或扩展正则表达式(由于默认值或由于某种原因的明确选择),以下解决方案将起作用:
通过反斜杠启用每个字符/组的扩展正则表达式的基本正则表达式:
grep -G '([0-9][0-9]:[0-9][0-9]\(:[0-9][0-9]\)\?)' /path/to/doc
# Using extended regex "{2}" for "previous char/group two times"
# which has the exact same meaning and regex length as above:
grep -G '([0-9]\{2\}:[0-9]\{2\}\(:[0-9]\{2\}\)\?)' /path/to/doc
# Less specific, allowing "(7:24:13)" but also "(3432:0054:1)"
grep -G '([0-9]\+:[0-9]\+\(:[0-9]\+\)\?)' /path/to/doc
扩展正则表达式:
grep -E '\([0-9]{2}:[0-9]{2}(:[0-9]{2})?\)' /path/to/doc
# Less specific, allowing "(7:24:13)" but also "(3432:0054:1)"
grep -E '\([0-9]+:[0-9]+(:[0-9]+)?\)' /path/to/doc