Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
597 views
in Technique[技术] by (71.8m points)

bash - How do I use a regex in a shell script?

I am trying to match a string with a regex in a shell script. This string is a parameter of the script ( $1 ) and it is a date (MM/DD/YYYY) The regex I'm trying to use is :

^d{2}[/-]d{2}[/-]d{4}$

It seems to work, I tried it on several regex tests websites.

My shell code is :

REGEX_DATE="^d{2}[/-]d{2}[/-]d{4}$"
?
echo "$1" | grep -q $REGEX_DATE
echo $?

The "echo $?" returns 1 no matter is the string I'm putting in parameter.

Do you guys have an idea ?

Thanks !

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To complement the existing helpful answers:

Using Bash's own regex-matching operator, =~, is a faster alternative in this case, given that you're only matching a single value already stored in a variable:

set -- '12-34-5678' # set $1 to sample value

kREGEX_DATE='^[0-9]{2}[-/][0-9]{2}[-/][0-9]{4}$' # note use of [0-9] to avoid d
[[ $1 =~ $kREGEX_DATE ]]
echo $? # 0 with the sample value, i.e., a successful match

Note, however, that the caveat re using flavor-specific regex constructs such as d equally applies: While =~ supports EREs (extended regular expressions), it also supports the host platform's specific extension - it's a rare case of Bash's behavior being platform-dependent.

To remain portable (in the context of Bash), stick to the POSIX ERE specification.

Note that =~ even allows you to define capture groups (parenthesized subexpressions) whose matches you can later access through Bash's special ${BASH_REMATCH[@]} array variable.

Further notes:

  • $kREGEX_DATE is used unquoted, which is necessary for the regex to be recognized as such (quoted parts would be treated as literals).

  • While not always necessary, it is advisable to store the regex in a variable first, because Bash has trouble with regex literals containing .

    • E.g., on Linux, where < is supported to match word boundaries, [[ 3 =~ <3 ]] && echo yes doesn't work, but re='<3'; [[ 3 =~ $re ]] && echo yes does.
  • I've changed variable name REGEX_DATE to kREGEX_DATE (k signaling a (conceptual) constant), so as to ensure that the name isn't an all-uppercase name, because all-uppercase variable names should be avoided to prevent conflicts with special environment and shell variables.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...