স্টেটমেন্টে বাশ-এ রিজেক্স ম্যাচিং


89

আমি এখানে কি ভুল করেছি?

শূন্যস্থান, ছোট হাতের অক্ষর, বড় হাতের সংখ্যা বা সংখ্যাসমৃদ্ধ যে কোনও স্ট্রিংয়ের সাথে মিলের চেষ্টা করা। বিশেষ অক্ষরগুলিও দুর্দান্ত লাগবে তবে আমি মনে করি এটির জন্য নির্দিষ্ট অক্ষরগুলি পালিয়ে যাওয়া দরকার।

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'

আপনি আসলে কোন শেল ব্যবহার করছেন? / বিন / শ? / বিন / বাশ? / বিন / সিএসএস?
উইলেম ভ্যান অনসেম

8
একটি ভেরিয়েবলে রেজেক্স স্থাপন করা নিরাপদ। re='...whatever...'; [[ $string =~ $re ]](উদ্ধৃতি ব্যতীত - এটি এমন একটি বিরল ঘটনা যেখানে তারা এমন কিছু ভেঙে ফেলবে যা এগুলি ছাড়া কার্যকর হবে)।
চার্লস ডাফি

4
পরিবর্তে অ্যাসাইনমেন্টের চারপাশে একক উদ্ধৃতি রাখুন। ডাবল উদ্ধৃতিগুলি বিশেষ অক্ষরগুলি সঠিকভাবে রক্ষা করবে না।
ট্রিপলি

অনেক থেক্স থার্ড চার্লস! এটি এখনও ভেরিয়েবলের মধ্যে রাখছে না ঠিক আছে, তবে এটি অবশ্যই উদ্ধৃত করা উচিত নয়! উদাহরণস্বরূপ: [[ $var =~ .* ]]ম্যাচ রেজেক্সের জন্য .*(যে কোনও কিছু)। আমি অনুমান করি আপনি যদি উদ্ধৃতি ব্যবহার করেন তবে উক্ত উদ্ধৃতিগুলি তাদেরকে রেজেক্সের অংশ হিসাবে বিবেচনা করা হয় ...
স্টাফেন

4
গ্যাচা সংক্ষিপ্তসারটি আমি খুঁজে পেয়েছি: (১.) pattern='^hello[0-9]*$'ডাবল বর্গাকার এক্সপ্রেশনতে একক উদ্ধৃতি (২) ব্যবহার করে কোনও চলকটিতে প্যাটার্নটি সংরক্ষণ করুন আপনার যদি রিজেক্স ম্যাচিং দরকার হয় তবে প্যাটার্নটি উদ্ধৃত করবেন না কারণ রেজিগ্স প্যাটার্নের মিলটি উদ্ধৃত করে। (অর্থাৎ অভিব্যক্তিটি [[ "$x" =~ $pattern ]]রেজেক্স ব্যবহার করে [[ "$x" =~ "$pattern" ]]মিলবে এবং এক্সপ্রেশনটি রেজেক্স ম্যাচটি অক্ষম করে এবং এর সমতুল্য[[ "$x" == "$pattern" ]] )।
ট্রেভর বয়েড স্মিথ

উত্তর:


184

বাশের [[ ]]নির্মাণ সম্পর্কে কয়েকটি গুরুত্বপূর্ণ বিষয় জানতে হবে । প্রথম:

ওয়ার্ড বিভাজন এবং পথনাম সম্প্রসারণ মধ্যে শব্দের উপর সঞ্চালিত হয় না [[এবং ]]; টিলডে এক্সপেনশন, প্যারামিটার এবং ভেরিয়েবল এক্সপেনশন, পাটিগণিতের সম্প্রসারণ, কমান্ড প্রতিস্থাপন, প্রক্রিয়া প্রতিস্থাপন এবং উদ্ধৃতি অপসারণ সম্পাদন করা হয় performed

দ্বিতীয় জিনিস:

অতিরিক্ত বাইনারি অপারেটর, '= ~' উপলভ্য, ... অপারেটরের ডানদিকে স্ট্রিং একটি বর্ধিত নিয়মিত অভিব্যক্তি হিসাবে বিবেচনা করা হয় এবং তদনুসারে ম্যাচ করা হয় ... প্যাটার্নের কোনও অংশই এটির সাথে জোর করতে বাধ্য করা যেতে পারে একটি স্ট্রিং হিসাবে

ফলস্বরূপ, এর $vউভয় পাশে =~সেই চলকের মানে প্রসারিত হবে, তবে ফলাফলটি শব্দ বিভাজন বা পথের নাম-প্রসারিত হবে না। অন্য কথায়, বাম-হাতের দিকের পরিবর্তনশীল বিস্তৃতিগুলি নিখুঁতভাবে ছেড়ে দেওয়া পুরোপুরি নিরাপদ তবে আপনার এটি জানতে হবে যে পরিবর্তনশীল বিস্তৃতি ডান হাতের দিকে ঘটবে।

তাই আপনি যদি লিখুন: [[ $x =~ [$0-9a-zA-Z] ]], $0ডান দিকে Regex ভিতরে আগে Regex ব্যাখ্যা করা হয় সম্প্রসারিত হবে, যা সম্ভবত কম্পাইল করার (ব্যর্থ Regex কারণ হবে, যদি না সম্প্রসারণ $0একটি অঙ্ক বা যতিচিহ্ন প্রতীক সঙ্গে প্রান্ত যার ASCII মান কম একটি অঙ্ক)। আপনি যদি ডান হাতের মতো [[ $x =~ "[$0-9a-zA-Z]" ]]একইভাবে উদ্ধৃতি দেন তবে ডান হাতটি একটি সাধারণ স্ট্রিং হিসাবে বিবেচনা করা হবে, রেজেক্স নয় (এবং $0এখনও প্রসারিত হবে)। এই ক্ষেত্রে আপনি যা চান তা হ'ল[[ $x =~ [\$0-9a-zA-Z] ]]

একইভাবে, মধ্যে অভিব্যক্তি [[এবং ]]সামনে Regex ব্যাখ্যা করা হয় শব্দ বিভক্ত করা হয়। সুতরাং রেজেক্সের ফাঁকা স্থানগুলি এড়ানো বা উদ্ধৃত হওয়া দরকার। আপনি অক্ষর, সংখ্যা বা স্পেস মেলে চেয়েছিলেন আপনি ব্যবহার করতে পারে: [[ $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 ...

!পরীক্ষাকে অবহেলা করে, এটিকে "মেলে না" অপারেটর হিসাবে রূপান্তরিত করে এবং একটি [^...]রেজেক্স চরিত্র শ্রেণীর অর্থ "ব্যতীত অন্য কোনও চরিত্র ..."।

প্যারামিটার সম্প্রসারণ এবং রেজেক্স অপারেটরগুলির সংমিশ্রণে বাশকে নিয়মিত এক্সপ্রেশন সিনট্যাক্স তৈরি করতে পারে "প্রায় পাঠযোগ্য", তবে এখনও কিছু গোটাচ রয়েছে। (সর্বদা থাকে না?) একটি হ'ল আপনি প্রথমে বাদে উদ্ধৃতি দিয়ে থাকলেও ]into োকাতে $validপারেন $validনি। (এটা একটা Posix Regex নিয়ম: আপনি অন্তর্ভুক্ত করতে চান ]। একটি অক্ষর বর্গ, এটা শুরুতে যেতে প্রয়োজন -শুরুতে বা শেষে যেতে পারেন, তাই যদি আপনি উভয় প্রয়োজন ]এবং -আপনার সাথে শুরু করতে ]এবং শেষ -, "আমি জানি আমি কি করছি" ইমেটিকনকে রেইজেক্সের দিকে নিয়ে যাওয়া [][-]:)


6
কেবল উল্লেখ করতে চাই যে "! ~" "অপারেটরের সাথে মেলে না " এটি সত্য নয়। হয় ব্যবহার if ! [[ $x =~ $y ]]বাif [[ ! $x =~ $y ]]
অ্যালকোহল

শেলচেকার একমত নন ...SC2076: Don't quote rhs of =~, it'll match literally rather than as a regex.
লিওনার্দো

4
@ লিওনার্ড: কীভাবে এটি "আপনি পরিবর্তনশীল প্রসারণের উদ্ধৃতি দিতে পারবেন না" এবং "এটি কাজ করে না" মন্তব্যটি থেকে কীভাবে আলাদা? এ সম্পর্কে কী অস্পষ্ট?
ধনী

4
@ জিনবিওমহং: সাদা বাক্সটি ব্যবহার করে অভিব্যক্তিটি যথারীতি শব্দগুলিতে বিভক্ত হয়। তবে প্যারামিটার এবং কমান্ডের বিস্তৃতি শব্দ-বিভক্ত নয়।
ধনী

4
@ জিনবিওমহং: আমি বাশ ম্যানুয়াল থেকে আলাদা কিছু বলছি না। " এবং " এর মধ্যে শব্দগুলি প্রোগ্রামের পাঠ্য থেকে পৃথক করা হয়, একইভাবে কমান্ড লাইনগুলিকে শব্দগুলিতে পার্স করা হয়। কমান্ড লাইনের বিপরীতে যদিও শব্দগুলি বিস্তৃত হওয়ার পরে বিভক্ত হয় না। [[]]
ধনী

30

যদি কেউ ভেরিয়েবল ব্যবহার করে উদাহরণ চায় ...

#!/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:]]+$ ]]

-1

অথবা আপনি এই প্রশ্নটির দিকে তাকিয়ে থাকতে পারেন কারণ আমার মতো নির্বোধ টাইপ করার মতো ঘটনা ঘটেছে এবং তার সাথে = vers বিপরীত ~ =

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.