Bash'in [[ ]]
inşası hakkında bilinmesi gereken birkaç önemli şey var . İlk:
Sözcük bölme ve yol adı genişletme, [[
ve arasındaki sözcüklerde gerçekleştirilmez ]]
; yaklaşık genişletme, parametre ve değişken genişletme, aritmetik genişletme, komut ikamesi, işlem ikamesi ve alıntı kaldırma gerçekleştirilir.
İkinci şey:
Ek bir ikili işleç, '= ~' mevcuttur, ... işlecin sağındaki dize, genişletilmiş bir normal ifade olarak kabul edilir ve buna göre eşleştirilir ... Eşleşmeye zorlamak için modelin herhangi bir kısmı tırnak içine alınabilir bir dize olarak .
Sonuç olarak, $v
her iki tarafında da =~
o değişkenin değerine genişletilecek, ancak sonuç sözcük ayrımı veya yol adı genişletme olmayacaktır. Diğer bir deyişle, değişken genişletmeleri sol tarafta alıntılanmamış bırakmak tamamen güvenlidir, ancak değişken genişletmelerin sağ tarafta olacağını bilmeniz gerekir.
Yazdığınız Yani eğer: [[ $x =~ [$0-9a-zA-Z] ]]
, $0
regex yorumlanır önce sağdaki regex içine muhtemelen (derlemeye başarısız olmasına regex neden olacaktır, genişletilecek genişlemesi sürece $0
kimin ASCII değeri az olan bir rakam ya da noktalama sembolüyle uçları bir rakam). Sağ taraftan böyle alıntı yaparsanız, sağ taraf [[ $x =~ "[$0-9a-zA-Z]" ]]
normal bir dize olarak değerlendirilir, normal bir dize olarak değerlendirilir (ve $0
yine de genişletilir). Bu durumda gerçekten istediğiniz şey[[ $x =~ [\$0-9a-zA-Z] ]]
Benzer şekilde, normal ifade yorumlanmadan önce [[
ve arasındaki ifade ]]
kelimelere bölünür. Bu nedenle, normal ifadedeki boşluklardan kaçınılması veya alıntı yapılması gerekir. Eğer harf, rakam veya boşluk maç istiyorsa şunu kullanabilirsiniz: [[ $x =~ [0-9a-zA-Z\ ] ]]
. Benzer şekilde, #
alıntı yapılmazsa bir yorum başlatacak gibi diğer karakterlerden de kaçınılması gerekir . Elbette, modeli bir değişkene koyabilirsiniz:
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
Bash'in sözlüğünden geçmek için kaçılması veya alıntı yapılması gereken çok sayıda karakter içeren normal ifadeler için, birçok kişi bu stili tercih eder. Ancak dikkat edin: Bu durumda, değişken genişletmeyi alıntı yapamazsınız :
if [[ $x =~ "$pat" ]]; then ...
Son olarak, yapmaya çalıştığınız şeyin değişkenin yalnızca geçerli karakterler içerdiğini doğrulamak olduğunu düşünüyorum. Bu kontrolü yapmanın en kolay yolu, geçersiz bir karakter içermediğinden emin olmaktır. Başka bir deyişle, şöyle bir ifade:
valid='0-9a-zA-Z $%&#'
if [[ ! $x =~ [^$valid] ]]; then ...
!
testi geçersiz kılar, "eşleşmiyor" operatörüne dönüştürür ve bir [^...]
normal ifade karakter sınıfı "dışındaki herhangi bir karakter" anlamına gelir ...
.
Parametre genişletme ve normal ifade operatörlerinin birleşimi, bash düzenli ifade sözdizimini "neredeyse okunabilir" hale getirebilir, ancak yine de bazı bilgiler vardır. (Her zaman yok mu?) Biri koymak olamazdı ki ]
içine $valid
bile $valid
çok başlayan haricinde, sözleri kaydedildi. (Bu bir Posix normal ifade kuralıdır: ]
Bir karakter sınıfına dahil etmek istiyorsanız , baştan gitmesi gerekir. -
Başa veya sona gidebilir, bu nedenle ikisine de ihtiyacınız varsa ]
ve -
şununla başlamalısınız:]
ve bitmeniz-
, regex giden ifadeyi "Ben ne yaptığımı biliyorum": [][-]
)