Nedávno som narazil na situáciu, keď som robil nejakú domácu prácu s regulárnymi výrazmi.
s@ubuntu:~$ echo b | egrep []b]
b
s@ubuntu:~$ echo b | egrep [[b]
b
s@ubuntu:~$ echo b | egrep []b[]
b
s@ubuntu:~$ echo b | egrep [b[]
b
s@ubuntu:~$ echo b | egrep [[b]]
s@ubuntu:~$ echo b | egrep [b]]
s@ubuntu:~$ echo b | egrep [b]]
s@ubuntu:~$ echo b | egrep [b\]]
s@ubuntu:~$ echo b | egrep [[b]]
Prečo sa v posledných piatich prípadoch nezobrazuje "b"?
odpovede:
3 pre odpoveď č. 1Dôvodom je to v osobitných pravidlách, ktoré sa uplatňujú vo vnútri výrazových zátvoriek:
Pravá štvorhranná konzola
]
musia byť umiestnené hneď po otvorení[
alebo[^
považovať za doslovné.
a
Únikový znak
sa zaobchádza doslovne v triede chars
[...]
Pri návyku sa na shell použije únikový znak pred prejdením výrazu na
egrep
, kvôli chýbajúcemu singlu "..."
alebo dvojitých úvodzoviek "..."
okolo regexu.
Jonathan Leffler to dobre vysvetlí pomocou príkladov, môžem len uviesť odkaz na pravidlá rozšírenia Posix v zátvorkách a pridať prehľad:
http://pubs.opengroup.org/onlinepubs/007904875/basedefs/xbd_chap09.html#tag_09_03_05
UPDATE
Rovnaké výrazy s citátmi:
# this matches "b]" or "]"
~$ echo b] | egrep "[b]]"
b]
~$ echo "]" | egrep "[b]]" # note the quotes prior and after the pipe
]
# the next one is equivalent to "[b]]"
# cause a double inside chars class is redundant
~$ echo b] | egrep "[b\]]"
b]
~$ echo "]" | egrep "[b\]]"
]
# the last one matches "]" or "[]" or "b]"
~$ echo b] | egrep "[[b]]"
[b]
~$ echo [] | egrep "[[b]]"
[]
~$ echo "]" | egrep "[[b]]"
]
# without quotes in the echo section, the escape is applied by the shell
# so egrep receive only a closing bracket "]" and nothing is printed out
~$ echo ] | egrep "[[b]]"
# If we remove instead the quotes from the egrep section
# the regex becomes equivalent to [[b]] so it now matches "[]" or "b]" and not "]" anymore
~$ echo "]" | egrep [[b]]
~$ echo "[]" | egrep [[b]]
[]
~$ echo "b]" | egrep [[b]]
b]
5 pre odpoveď № 2
egrep [[b]]
- Vyzerá tob
alebo[
nasleduje a]
; nenájdené.egrep [b]]
- Vyzerá tob
nasleduje a]
; nenájdené.egrep [b]]
- Vyzerá tob
nasleduje a]
; nenájdené. Spätné lomítko je vynechané škrupinou a nie je vidieťegrep
.egrep [b\]]
- Vyzerá tob
alebo spätné lomítko nasledované]
; nenájdené.egrep [[b]]
- Vyzerá tob
alebo a[
nasledovaný]
; nenájdené. Spätné lomky sú vynechané škrupinou a nie sú viditeľnéegrep
.
Vo vnútri triedy znakov (začal [
), prvý ]
ukončí triedu, pokiaľ ]
je prvý znak po [
, alebo prvý znak po [^
pre negovanú triedu znakov. Poznač si to ]
nie je regex metacharakter, pokiaľ nie je predchádzajúci [
čím sa stáva koncom triedy postáv. Tiež to nájdete $
nie je metaznačkou uprostred reťazca, ani ^
pokiaľ sa nezobrazí na začiatku, ani *
ani +
ani ?
ak sa zobrazia ako prvé atď. Pozri POSIX Pravidelné výrazy pre podrobnú diskusiu - regulárne výrazy, s ktorými sa zaoberá egrep
(teraz grep -E
) sú "rozšírené regulárne výrazy".
Oheň sa predtým mieša s opačnými lomami egrep
dostane šancu vidieť ich. Mali by ste priložiť svoj regex do jednoduchých úvodzoviek, aby sa zabránilo tomu, že shell zmení čo egrep
vidí.
Môžete preukázať svoju analýzu zmenou toho, čo sa ozýva:
echo "[b]" | egrep [[b]]
echo "[b]" | egrep [b]]
echo "[b]" | egrep [b]]
echo "[b]" | egrep [b\]]
echo "[b]" | egrep [[b]]
Výsledkom je:
[b]
[b]
[b]
[b]
[b]
Na [
v týchto príkladoch (v zopakoval údajov) je prítomná z kozmetických dôvodov; mohol byť vynechaný a riadky budú prijaté.