Аз имам проблеми с регекс, имам нужда от търсене и премахване на модела, съответстващ на регекс, когато се намери, че трябва да отрязвам. Написах такъв регекс
regex="(.*)((aa[[:space:]]bb)|(awd)|(bab)|(bc[[:space:]]d))(*.)"
в който определям цялото начало (1), частта, в която може да бъде мишената (2) и целият край (3). Това е лесно с проста регекс като (.) (ABC) (.) низ = "ABC"; регулярен = "(.) (ABC) (.) "
[[ $string =~ $regex) && myvar=${BASH_REMATCH[2]} && buffer=${BASH_REMATCH[1]}${BASH_REMATCH[3]}
Проблемът започва, когато дефинирам регенериране с вложени паренчета и OR групи, както и първият регекс, публикуван тук. Това е мостра от моята черупка:
$ string=" foo bar baz bac"
$ regex="(.*)((hello[[:space:]]world)|(example)|(funk[[:space:]]you)|(bar[[:space:]]baz))(.*)"
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[1]}
foo
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[2]}
bar baz
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[3]}
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[4]}
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[5]}
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[6]}
bar baz
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[7]}
bac
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[@]}
foo bar baz bac foo bar baz bar baz bac
Съответствието има странно поведение, не намирам другата част от входния низ в $ {BASH_REMATCH [3]}, въпреки че е в третата паренса на регенезата. Какво се случва с вложени паренчета?
Отговори:
1 за отговор № 1bash
присвоява номера на групите за заснемане въз основа на реда от ляво на дясно на отварящите скоби. По същество това е първа поръчка на дълбочина, а не ширина - първо, както предполагате.
1. (.*)
2. (
3. (hello[[:space:]]world)|
4. (example)|
5. (funk[[:space:]]you)|
6. (bar[[:space:]]baz)
)
7. (.*)
В този регулярен израз групата 2 епо същество копие на която и да е от групите 3, 4, 5 или 6 действително съвпада, тъй като група 2 не съдържа нищо друго. Група 7 е това, което смятате за трета група.
Група 0 е целият мач, който обяснява последната ви линия @
:
$ [[ $string =~ $regex ]] && echo ${BASH_REMATCH[@]}
foo bar baz bac foo bar baz bar baz bac
| | | | | | | | | |
+-------------+ +-+ +-----+ +-----+ +-+
0 1 2 6 7
(Празните групи 3, 4 и 5 се поглъщат като празно пространство по време на разделяне на думи.)