That
\N*\.(\D{2}|\D{3})$
Is a perl regexp. bash's [[ =~ ]]
operator takes a POSIX extended regexp, not a perl regexp.
To use a perl-style regexp, use zsh and its rematchpcre
option:
set -o rematchpcre
[[ $ns =~ '\N*\.(\D{2}|\D{3})$' ]]
Now, that regexp doesn't make much sense.
\N
is meant to match on any character other than newline, but unless you set the s
flag (like with (?s)
), .
won't match a newline anyway so you could replace \N
with .
.
- Having
<anything>*
at the start or end of a regexp is pointless as it matches on 0 or more of <anything>
, so it matches on nothing as well. [[ $ns =~ '\.(\D{2}|\D{3})$' ]]
is functionally equivalent.
\D
matches on any character other than decimal digits which are either 0123456789 or something like 0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९০১২৩৪৫৬৭৮৯੦੧੨੩੪੫੬੭੮੯૦૧૨૩૪૫૬૭૮૯୦୧୨୩୪୫୬୭୮୯௦௧௨௩௪௫௬௭௮௯౦౧౨౩౪౫౬౭౮౯೦೧೨೩೪೫೬೭೮೯൦൧൨൩൪൫൬൭൮൯෦෧෨෩෪෫෬෭෮෯๐๑๒๓๔๕๖๗๘๙໐໑໒໓໔໕໖໗໘໙༠༡༢༣༤༥༦༧༨༩၀၁၂၃၄၅၆၇၈၉႐႑႒႓႔႕႖႗႘႙០១២៣៤៥៦៧៨៩᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏᧐᧑᧒᧓᧔᧕᧖᧗᧘᧙᪀᪁᪂᪃᪄᪅᪆᪇᪈᪉᪐᪑᪒᪓᪔᪕᪖᪗᪘᪙᭐᭑᭒᭓᭔᭕᭖᭗᭘᭙᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙꘠꘡꘢꘣꘤꘥꘦꘧꘨꘩꣐꣑꣒꣓꣔꣕꣖꣗꣘꣙꤀꤁꤂꤃꤄꤅꤆꤇꤈꤉꧐꧑꧒꧓꧔꧕꧖꧗꧘꧙꧰꧱꧲꧳꧴꧵꧶꧷꧸꧹꩐꩑꩒꩓꩔꩕꩖꩗꩘꩙꯰꯱꯲꯳꯴꯵꯶꯷꯸꯹0123456789 depending on whether the matching is done based on Unicode character properties or not (not by default in zsh unless you add (*UCP)
). So that also matches on .
characters which makes your check fall apart.
\D{2}|\D{3}
can be written \D{2,3}
$
in perl regexps matches on either the end of the subject or before a newline character at the end of the subject. To match at the end of the subject, you use \z
instead.
So assuming you want to match on strings that end with .
followed by 2 to 3 characters other than digits and .
, with PCRE, you'd need:
# zsh
set -o rematchpcre
[[ $ns =~ '\.[^\d.]{2,3}\z' ]]
Or with ERE:
# zsh/bash -O compat31
[[ $ns =~ '\.[^[:digit:].]{2,3}$' ]]
Or:
# zsh/bash/ksh93
regex='\.[^[:digit:].]{2,3}$'
[[ $ns =~ $regex ]]
Bearing in mind that what [[:digit:]]
matches varies with the locale and system. Use [^0123456789.]
to match on any character other than .
and those specific decimal digit characters.
\D
, [^\d.]
and [^[:digit:].]
all also match on newline characters. If you wanted to make sure strings that contain a newline characters don't match, you'd need regex='^.*\.[^\d\n.]{2,3}\z'
(or regex='^\N*\.[^\d\n.]{2,3}\z'
to make it more explicit) in perl-style RE and regex=$'^[^\n]*\.[^[:digit:].\n]{2,3}$'
in ERE.
grep
,sed
, andawk
. While some websites may offer helpful features like syntax highlighting and debugging tools, they may not accurately reflect how your regular expression will behave with standard Unix tools. – Kusalananda Oct 07 '23 at 09:30