我正在努力了解在编写正则表达式时如何防止在寻找模式之前或之后存在某些模式!
我正在寻找一个正则表达式,它将匹配长字符串中YYMMDD((([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1]))
)格式的日期,同时忽略更长的数字序列
它应该能够匹配:
但忽略:
如果一个数字比这6个数字更多,我怎么能确保它不会在一个正则表达式中被选为日期(意思是,我宁愿避免预处理字符串)
我曾想过\D((19|20)([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1]))\D
,但这是不是意味着必须某个角色之前和之后?
我正在使用bash 3.2(ERE)
谢谢!
答案 0 :(得分:1)
尝试:
#!/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
答案 1 :(得分:0)
如果您的令牌是行分隔的(即每行只有一个令牌):
^[\D]*[\d]{6}([\D]*|[\D]+[\d]{1,6})$
基本上,这个正则表达式代表:
此正则表达式传递了所有给定的样本输入。
答案 2 :(得分:0)
您可以使用非捕获组在日期正则表达式的任一侧定义非数字。我成功使用了这个表达式和相同的测试数据。
(?:\D)([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])(?:\D)