Bash regex group capture


22

ฉันพยายามจับคู่ค่าตัวอักษรและตัวเลขหลายตัว (ตัวเลขนี้อาจแตกต่างกันไป) จากสตริงและบันทึกลงในอาร์เรย์กลุ่มการจับภาพทุบตี อย่างไรก็ตามฉันได้รับนัดแรกเท่านั้น:

mystring1='<link rel="self" href="/unix//api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/unix//api/clouds/1/instances/2AAAAAAA"/>'

regex='/instances/([A-Z0-9]+)'

[[ $mystring1 =~ $regex ]]

echo ${BASH_REMATCH[1]}
1BBBBBB

echo ${BASH_REMATCH[2]}

อย่างที่คุณเห็นมันตรงกับค่าแรกที่ฉันกำลังค้นหา แต่ไม่ใช่ค่าที่สอง


1
คุณจะพอใจกับการวนลูปมากกว่าเอาท์พุทecho "$mystring1" | grep -oE '/instances/([A-Z0-9]+)'หรือไม่
Jeff Schaller

4
น่าจะพูดถึงคนดังคุณไม่สามารถแยก HTML กับโพสต์regex
Digital Trauma

คำตอบ:


22

มันเป็นความอัปยศที่คุณไม่สามารถทำการจับคู่ทั่วโลกในการทุบตี คุณสามารถทำได้:

global_rematch() { 
    local s=$1 regex=$2 
    while [[ $s =~ $regex ]]; do 
        echo "${BASH_REMATCH[1]}"
        s=${s#*"${BASH_REMATCH[1]}"}
    done
}
global_rematch "$mystring1" "$regex" 
1BBBBBB
2AAAAAAA

การทำงานนี้โดยการตัดส่วนนำหน้าที่ตรงกันออกจากสตริงเพื่อให้สามารถจับคู่ส่วนถัดไปได้ มันทำลายสตริง แต่ในฟังก์ชั่นมันเป็นตัวแปรท้องถิ่นดังนั้นใครสนใจ

ฉันจะใช้ฟังก์ชั่นนั้นเพื่อเติมอาเรย์:

$ mapfile -t matches < <( global_rematch "$mystring1" "$regex" )
$ printf "%s\n" "${matches[@]}"
1BBBBBB
2AAAAAAA

ขอบคุณ - ดูเหมือนว่าวิธีแก้ปัญหาที่ทำงานได้เท่านั้นคือ mapfile ไม่มีอยู่ในทุบตี 3.2 ...
Arthur Lyssenko

1
ดูmywiki.wooledge.org/BashFAQ/001เพื่อหาทางเลือกอื่น ๆ
glenn jackman

6

ในการรับค่าอาร์เรย์ที่สองคุณต้องมีวงเล็บชุดที่สองใน regex:

mystring1='<link rel="self" href="/unix//api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/unix//api/clouds/1/instances/2AAAAAAA"/>'

regex='/instances/([A-Z0-9]+).*/instances/([A-Z0-9]+)'

[[ $mystring1 =~ $regex ]]

$ echo ${BASH_REMATCH[1]}
1BBBBBB
$ echo ${BASH_REMATCH[2]}
2AAAAAAA

ขอบคุณทุกคนที่ฉันกำลังมองหาการแข่งขันที่เป็นไปได้จำนวนที่ไม่รู้จัก
Arthur Lyssenko

1
ฉันยกระดับคำถามของคุณเพราะฉันยังคาดหวังว่าจะมีการแข่งขันหลายรายการให้เข้าร่วมในอาร์เรย์ แต่ดูเหมือนว่าพวกเขาจะไม่ยกเว้นคุณจะมีวงเล็บหลายชุด
Jeff Schaller
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.