एक बयान में बैज में रेगेक्स मिलान


86

मैंने यहां क्या गलत किया?

रिक्त स्थान, लोअरकेस, अपरकेस या संख्याओं वाले किसी भी स्ट्रिंग से मिलान करने का प्रयास करना। विशेष वर्ण भी अच्छे होंगे, लेकिन मुझे लगता है कि कुछ पात्रों से बचने की आवश्यकता है।

TEST="THIS is a TEST title with some numbers 12345 and special char *&^%$#"

if [[ "$TEST" =~ [^a-zA-Z0-9\ ] ]]; then BLAH; fi

यह स्पष्ट रूप से केवल ऊपरी, निचले, संख्या और रिक्त स्थान के लिए परीक्षण करता है। हालांकि काम नहीं करता है।

* अपडेट करें *

मुझे लगता है कि मुझे और अधिक विशिष्ट होना चाहिए था। यहाँ कोड की वास्तविक वास्तविक रेखा है।

if [[ "$TITLE" =~ [^a-zA-Z0-9\ ] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; fi

* अपडेट करें *

./anm.sh: line 265: syntax error in conditional expression
./anm.sh: line 265: syntax error near `&*#]'
./anm.sh: line 265: `  if [[ ! "$TITLE" =~ [a-zA-Z0-9 $%^\&*#] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; return; fi'

आप वास्तव में किस खोल का उपयोग कर रहे हैं? / bin / श? / bin / bash? / bin / csh?
विलेम वैन ओन्सेम

8
रेगेक्स को एक चर में रखना अधिक सुरक्षित है। re='...whatever...'; [[ $string =~ $re ]](उद्धरण चिह्नों के बिना - यह उन दुर्लभ मामलों में से एक है जहां वे कुछ ऐसा तोड़ेंगे जो उनके बिना काम करेगा)।
चार्ल्स डफी

3
इसके बजाय असाइनमेंट के आसपास सिंगल कोट्स रखें। दोहरे उद्धरण विशेष वर्णों की ठीक से रक्षा नहीं करेंगे।
ट्रिपल

कई thx चार्ल्स! यह अभी भी एक चर में नहीं डाल ठीक है, लेकिन यह बिल्कुल उद्धृत नहीं किया जाना चाहिए! उदाहरण के लिए: [[ $var =~ .* ]]मैच रेगेक्स .*(कुछ भी) के लिए। मुझे लगता है कि यदि आप उद्धरण का उपयोग करते हैं, तो उद्धरण स्वयं को रेगेक्स का हिस्सा माना जाता है ...
स्टीफन

4
गेटा सारांश मैंने पाया: (1.) pattern='^hello[0-9]*$'डबल वर्ग अभिव्यक्ति में एकल उद्धरण (2.) का उपयोग करके एक चर में पैटर्न को बचाएं यदि आपको regex मिलान की आवश्यकता है तो पैटर्न को उद्धृत न करें क्योंकि regex पैटर्न मिलान को DISABLES उद्धृत करता है। (यानी एक्सप्रेशन [[ "$x" =~ $pattern ]]रेगेक्स का उपयोग करके मेल खाएगा और एक्सप्रेशन [[ "$x" =~ "$pattern" ]]रेगेक्स मैचिंग को निष्क्रिय कर देता है और इसके बराबर है[[ "$x" == "$pattern" ]] )।
ट्रेवर बॉयड स्मिथ

जवाबों:


177

बैश के [[ ]]निर्माण के बारे में जानने के लिए कुछ महत्वपूर्ण चीजें हैं । सबसे पहला:

पद बंटवारे और पथ नाम विस्तार के बीच शब्दों पर प्रदर्शन नहीं कर रहे हैं [[और ]]; टिल्ड विस्तार, पैरामीटर और चर विस्तार, अंकगणितीय विस्तार, कमांड प्रतिस्थापन, प्रक्रिया प्रतिस्थापन, और उद्धरण हटाने का प्रदर्शन किया जाता है।

दूसरी बात:

एक अतिरिक्त बाइनरी ऑपरेटर, '= ~' उपलब्ध है, ... ऑपरेटर के दाईं ओर स्ट्रिंग को एक विस्तारित नियमित अभिव्यक्ति माना जाता है और तदनुसार मिलान किया जाता है ... पैटर्न के किसी भी हिस्से को मिलान करने के लिए बाध्य करने के लिए उद्धृत किया जा सकता है। एक स्ट्रिंग के रूप में

नतीजतन, इच्छा के $vदोनों ओर =~उस चर के मूल्य में विस्तार किया जाएगा, लेकिन परिणाम शब्द-विभाजन या pathname- विस्तारित नहीं होगा। दूसरे शब्दों में, बाएं हाथ की ओर से निकले हुए चर विस्तार को छोड़ना पूरी तरह से सुरक्षित है, लेकिन आपको यह जानना होगा कि चर विस्तार दाएं हाथ की तरफ होगा।

तो अगर आप लिखें: [[ $x =~ [$0-9a-zA-Z] ]], $0सही पर regex अंदर से पहले regex व्याख्या की है विस्तार किया जाएगा, जो शायद संकलित करने के लिए (असफल करने के लिए regex का कारण होगा, जब तक के विस्तार $0अंक या विराम चिह्न के साथ समाप्त होता है जिसका ascii मूल्य से कम है एक अंक)। यदि आप दाहिने-हाथ की तरफ को कोट करते हैं [[ $x =~ "[$0-9a-zA-Z]" ]], तो -तो , दाहिने हाथ की तरफ एक साधारण स्ट्रिंग के रूप में माना जाएगा, न कि एक रेगेक्स (और $0अभी भी विस्तारित किया जाएगा)। इस मामले में आप वास्तव में क्या चाहते हैं[[ $x =~ [\$0-9a-zA-Z] ]]

इसी तरह, रेगेक्स की व्याख्या करने से पहले [[और उसके बीच के ]]शब्दों को शब्दों में विभाजित किया जाता है। तो रेगेक्स में रिक्त स्थान से बचने या उद्धृत करने की आवश्यकता है। आप अक्षर, अंक या रिक्त स्थान मिलान करना चाहते थे, तो आप इस्तेमाल कर सकते हैं: [[ $x =~ [0-9a-zA-Z\ ] ]]। अन्य पात्रों को भी इसी तरह से भाग जाने की जरूरत है, जैसे #, यदि उद्धृत नहीं किया गया तो एक टिप्पणी शुरू होगी। बेशक, आप पैटर्न को एक चर में डाल सकते हैं:

pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...

रेगेक्स के लिए, जिसमें बहुत सारे पात्र हैं, जिन्हें बश के लेक्सर के माध्यम से पारित होने से बचने या उद्धृत करने की आवश्यकता होती है, बहुत से लोग इस शैली को पसंद करते हैं। लेकिन सावधान रहें: इस मामले में, आप चर विस्तार को उद्धृत नहीं कर सकते :

# This doesn't work:
if [[ $x =~ "$pat" ]]; then ...

अंत में, मुझे लगता है कि आप जो करने की कोशिश कर रहे हैं वह यह सत्यापित करने के लिए है कि चर में केवल मान्य वर्ण हैं। इस चेक को करने का सबसे आसान तरीका यह सुनिश्चित करना है कि इसमें एक अमान्य चरित्र नहीं है। दूसरे शब्दों में, इस तरह एक अभिव्यक्ति:

valid='0-9a-zA-Z $%&#' # add almost whatever else you want to allow to the list
if [[ ! $x =~ [^$valid] ]]; then ...

!परीक्षण को नकारता है, इसे "मैच नहीं करता" ऑपरेटर में बदल देता है, और एक [^...]रेगीक्स वर्ण वर्ग का अर्थ है "के अलावा कोई भी चरित्र ..."।

पैरामीटर विस्तार और रेगेक्स ऑपरेटरों के संयोजन नियमित अभिव्यक्ति वाक्यविन्यास को "लगभग पठनीय" बना सकते हैं, लेकिन अभी भी कुछ गोच हैं। (हमेशा नहीं हैं?) एक वह है जिसे आप नहीं डाल ]सकते हैं $valid, भले ही $validउद्धृत किया गया हो, बहुत शुरुआत को छोड़कर। (यह एक पॉसिक्स रेगेक्स नियम है: यदि आप ]एक चरित्र वर्ग में शामिल करना चाहते हैं , तो इसे शुरुआत में जाने की आवश्यकता है -, शुरुआत या अंत में जा सकते हैं, इसलिए यदि आपको दोनों की आवश्यकता है ]और -, आपको इसके साथ शुरू करने ]और समाप्त करने की आवश्यकता है -,) regex के लिए अग्रणी "मुझे पता है कि मैं क्या कर रहा हूँ" इमोटिकॉन: [][-])


6
बस यह इंगित करना चाहते हैं कि "~!" से मेल नहीं खाता "ऑपरेटर" सच नहीं है। या तो उपयोग करें if ! [[ $x =~ $y ]]याif [[ ! $x =~ $y ]]
शराब

शेल्केचर असहमत ...SC2076: Don't quote rhs of =~, it'll match literally rather than as a regex.
लियोनार्डो

4
@leonard: यह मेरे कथन से भिन्न नहीं है "आप चर विस्तार का उद्धरण नहीं दे सकते हैं" और टिप्पणी "यह काम नहीं करता है"? उसके बारे में क्या अस्पष्ट है?
रिसी

1
@jinbeomhong: अभिव्यक्ति को हमेशा की तरह शब्दों में अलग करके व्हाट्सएप का उपयोग किया जाता है। लेकिन पैरामीटर और कमांड विस्तार शब्द-विभाजन नहीं हैं।
रिसी

1
@jinbeomhong: मैं बैश मैनुअल से अलग कुछ नहीं कह रहा हूं। " और " के बीच के शब्दों को प्रोग्राम टेक्स्ट से पार्स किया जाता है, उसी तरह कमांड लाइन को शब्दों में पार्स किया जाता है। कमांड लाइनों के विपरीत, हालांकि, शब्द विस्तार के बाद विभाजित नहीं होते हैं। [[]]
रिसी

26

मामले में किसी को चर का उपयोग करके एक उदाहरण चाहिए था ...

#!/bin/bash

# Only continue for 'develop' or 'release/*' branches
BRANCH_REGEX="^(develop$|release//*)"

if [[ $BRANCH =~ $BRANCH_REGEX ]];
then
    echo "BRANCH '$BRANCH' matches BRANCH_REGEX '$BRANCH_REGEX'"
else
    echo "BRANCH '$BRANCH' DOES NOT MATCH BRANCH_REGEX '$BRANCH_REGEX'"
fi

13

मैं [:punct:]उस के लिए उपयोग करना चाहते हैं । इसके अलावा, a-zA-Z09-9बस हो सकता है [:alnum:]:

[[ $TEST =~ ^[[:alnum:][:blank:][:punct:]]+$ ]]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.