Regex 匹配YYMMDD但不匹配更长数字的bash正则表达式 一般问题
我试图理解,在编写正则表达式时,如何防止在寻找到的模式之前或之后存在某种模式 一个更具体的例子 我正在寻找一个正则表达式,它将在一个长字符串中匹配YYMMDD(Regex 匹配YYMMDD但不匹配更长数字的bash正则表达式 一般问题,regex,bash,macos,Regex,Bash,Macos,我试图理解,在编写正则表达式时,如何防止在寻找到的模式之前或之后存在某种模式 一个更具体的例子 我正在寻找一个正则表达式,它将在一个长字符串中匹配YYMMDD(([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1]))格式的日期,同时忽略更长的数字序列 它应该能够匹配: 文本151124moretext 123text 151124moretext 文本151124 text 151124moretext1944 151124 但是应该忽略:
([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])
)格式的日期,同时忽略更长的数字序列
它应该能够匹配:
- 文本151124moretext
- 123text 151124moretext
- 文本151124
- text 151124moretext1944
- 151124
- 文本15112412更多文本 (原因:它有8个数字而不是6个)
- 151324 (原因:它不是有效日期YYMMDD-没有第13个月)
\D((19 | 20)([0-9]{2})(0[1-9]| 1[0-2])(0[1-9]|[1-2][0-9]| 3[0-1])\D
但这难道不意味着前后必须有一些字符吗
我正在使用Bash3.2(ERE)
谢谢 试试看:
#!/usr/bin/env bash
extract_date() {
local string="$1"
local _date=`echo "$string" | sed -E 's/.*[^0-9]([0-9]{6})[^0-9].*/\1/'`
#date -d $_date &> /dev/null # for Linux
date -jf '%y%m%d' $_date &> /dev/null # for MacOS
if [ $? -eq 0 ]; then
echo $_date
else
return 1
fi
}
extract_date text15111224moretext # ignore n_digits > 6
extract_date text151125moretext # take
extract_date text151132 # # ignore day 32
extract_date text151324moretext1944 # ignore month 13
extract_date text150931moretext1944 # ignore 31 Sept
extract_date 151126 # take
输出:
151125
151126
如果您的令牌是行分隔的(即每行只有一个令牌): 基本上,这个正则表达式寻找:
- 字符串开头任意数量的非数字李>
- 正好是6位数
- 任意数量的非数字,直到字符串的结尾,或至少一个非数字和至少一个数字(最多6个)
此正则表达式传递所有给定的示例输入。您可以使用非捕获组来定义日期正则表达式两侧的非数字。我成功地使用了这个表达式和您相同的测试数据
(?:\D)([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])(?:\D)
如果你使用
(^[0-9])…([^0-9]|$)
?什么没有断言?没有bash
3.4;你是说OSX附带的3.2版本,还是你自己安装的4.3版本?@chepner,啊,我错了——OSX附带的是3.2版本!谢谢你指出@sin,这是一个好机会!所有这些regex的味道都让我头疼,作为一个初学者,这真的让人望而生畏——看来我真正需要的是消极的前瞻。似乎ERE不支持消极前瞻-不是吗?谢谢@gregoux,这是一个有趣的方法!尽管如此,我还是在寻找一个能做到这一点的单一正则表达式;原因是我需要概括。现在我想起来了,表达我的问题的一个更好的方式是:在编写正则表达式时,我试图理解如何防止在寻找的模式之前或之后存在某种模式!然后您可以向上投票;)。您面临的问题是如何管理像9月31日False和2月28日False这样的案例。sed-r似乎在OSX中不起作用。sed-E代表增强(与扩展不同,但在特定表达式中它就足够了)()。OSX上的日期也不同;日期-d不起作用:我不得不用date-jf“%y%m%d”$\u date&>/dev/null
-如果您同意这些更改,您可以将它们集成到您的答案中,我将接受它们!作为旁注,150931
通过日期
评估(至少在OSX上)并转换为2015/10/01!对我来说,这是无关紧要的。谢谢你,泰德X!但是,我似乎无法将\D和\D与bash的[[=~]]操作符一起使用;运算符=~仅限于ERE-我弄错了吗?不确定这是否是我的错误,但似乎ERE不支持非捕获组和\D、\D等?
(?:\D)([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])(?:\D)