Ik probeer een string te matchen met een regex in een shellscript.
Deze string is een parameter van het script ( $1 ) en het is een datum (MM/DD/YYYY)
De regex die ik probeer te gebruiken is:
^\d{2}[\/\-]\d{2}[\/\-]\d{4}$
Het lijkt te werken, ik heb het op verschillende regex-testwebsites geprobeerd.
Mijn shell-code is:
REGEX_DATE="^\d{2}[\/\-]\d{2}[\/\-]\d{4}$"
echo "$1" | grep -q $REGEX_DATE
echo $?
De “echo $?” geeft 1 terug, ongeacht de tekenreeks die ik in de parameter plaats.
Hebben jullie een idee?
Bedankt!
Antwoord 1, autoriteit 100%
Ik denk dat dit is wat je wilt:
REGEX_DATE='^\d{2}[/-]\d{2}[/-]\d{4}$'
echo "$1" | grep -P -q $REGEX_DATE
echo $?
Ik heb de schakeloptie -P gebruikt om perl regex te krijgen.
Antwoord 2, autoriteit 92%
Als aanvulling op de bestaande nuttige antwoorden:
Het gebruik van Bash’s eigen regex-matching-operator, =~
, is in dit geval een sneller alternatief, aangezien u slechts een enkele waarde matcht die al is opgeslagen in een variabele:
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
Houd er echter rekening mee dat het voorbehoud bij het gebruik van smaakspecifieke regex-constructies zoals \d
evenzeer van toepassing is:
Hoewel =~
ERE’s ondersteunt (uitgebreidereguliere expressies), ondersteunt het ook de specifieke extensie van het hostplatform– het is een zeldzaam geval dat het gedrag van Bash platform is -afhankelijk.
Om draagbaar te blijven (in de context van Bash), houdt u zich aan de POSIX ERE-specificatie.
Merk op dat je met =~
zelfs capture groups(subexpressies tussen haakjes) kunt definiëren waarvan je later toegang kunt krijgen via Bash’s speciale ${BASH_REMATCH[@]}
matrixvariabele.
Verdere opmerkingen:
-
$kREGEX_DATE
wordt unquotedgebruikt, wat nodig is om de regex als zodanig te herkennen (geciteerde delen worden behandeld als literalsem>). -
Hoewel niet altijd nodig, is het raadzaam om de regex eerst in een variabele op te slaan, omdat Bash problemen heeft met regex literalsdie
\
bevatten.- Bijvoorbeeld op Linux, waar
\<
wordt ondersteund om woordgrenzen te matchen,[[ 3 =~ \<3 ]] && echo yes
werkt niet, maarre='\<3'; [[ 3 =~ $re ]] && echo yes
doet.
- Bijvoorbeeld op Linux, waar
-
Ik heb de variabelenaam
REGEX_DATE
gewijzigd inkREGEX_DATE
(k
geeft een (conceptuele) constante aan), om ervoor te zorgen dat dat de naam geen naam in hoofdletters is, omdat variabele in hoofdletters namen moeten worden vermeden om conflicten met speciale omgevings- en shell-variabelen te voorkomen.
Antwoord 3, autoriteit 33%
het probleem is dat u regex-functies probeert te gebruiken die niet door grep worden ondersteund. namelijk, uw \d
zal niet werken. gebruik in plaats daarvan dit:
REGEX_DATE="^[[:digit:]]{2}[-/][[:digit:]]{2}[-/][[:digit:]]{4}$"
echo "$1" | grep -qE "${REGEX_DATE}"
echo $?
je hebt de vlag -E
nodig om EREom de stijl {#}
te gebruiken.