/ / bash_rematch и regex (с вложени паренчета) - regex, bash, match

bash_rematch и regex (с вложени паренчета) - regex, bash, match

Аз имам проблеми с регекс, имам нужда от търсене и премахване на модела, съответстващ на регекс, когато се намери, че трябва да отрязвам. Написах такъв регекс

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 за отговор № 1

bash присвоява номера на групите за заснемане въз основа на реда от ляво на дясно на отварящите скоби. По същество това е първа поръчка на дълбочина, а не ширина - първо, както предполагате.

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 се поглъщат като празно пространство по време на разделяне на думи.)