Sed regexes จับคู่การแข่งขันที่ยาวที่สุด Sed ไม่เทียบเท่ากับความโลภ
เห็นได้ชัดว่าสิ่งที่เราต้องการจะทำคือการแข่งขัน
AB
,
ตามมาด้วย
- จำนวนเงินอื่นใดนอกเหนือจาก
AC
นั้น
ตามด้วย
AC
น่าเสียดายที่sed
อย่าทำ # 2 - อย่างน้อยก็ไม่ใช่สำหรับนิพจน์ทั่วไปที่มีหลายตัวอักษร แน่นอนว่าสำหรับตัวเดียวแสดงออกปกติเช่น@
(หรือแม้กระทั่ง[123]
) เราสามารถทำหรือ[^@]*
[^123]*
และเพื่อให้เราสามารถแก้ไขข้อ จำกัด ของ sed ได้โดยการเปลี่ยนทุกสิ่งAC
เป็นเป็น@
แล้วค้นหา
AB
,
ตามมาด้วย
- จำนวนสิ่งอื่นที่ไม่ใช่ใด ๆ
@
,
ตามมาด้วย
@
แบบนี้:
sed 's/AC/@/g; s/AB[^@]*@/XXX/; s/@/AC/g'
ส่วนสุดท้ายการเปลี่ยนแปลงกรณีที่เปรียบของกลับไป@
AC
แต่แน่นอนว่านี่เป็นวิธีที่ประมาทเนื่องจากอินพุตอาจมี@
อักขระอยู่แล้วดังนั้นโดยการจับคู่พวกเขาเราจะได้รับผลบวกปลอม อย่างไรก็ตามเนื่องจากไม่มีตัวแปรเชลล์จะมีอักขระ NUL ( \x00
) อยู่ในนั้นจึงน่าจะเป็นอักขระที่ดีที่จะใช้ในการทำงานด้านบนแทน@
:
$ echo 'ssABteAstACABnnACss' | sed 's/AC/\x00/g; s/AB[^\x00]*\x00/XXX/; s/\x00/AC/g'
ssXXXABnnACss
การใช้ NUL ต้องใช้ GNU sed (เพื่อให้แน่ใจว่าฟีเจอร์ของ GNU นั้นเปิดใช้งานผู้ใช้จะต้องไม่ตั้งค่าตัวแปรเชลล์ POSIXLY_CORRECT)
หากคุณใช้ sed กับ-z
ธงของ GNU เพื่อจัดการอินพุตที่คั่นด้วย NUL เช่นผลลัพธ์ของfind ... -print0
NUL แล้ว NUL จะไม่อยู่ในพื้นที่รูปแบบและ NUL เป็นตัวเลือกที่ดีสำหรับการทดแทนที่นี่
แม้ว่า NUL ไม่สามารถอยู่ในตัวแปร bash ได้ แต่ก็เป็นไปได้ที่จะรวมไว้ในprintf
คำสั่ง หากสตริงอินพุตของคุณสามารถมีอักขระใด ๆ ได้รวมถึง NUL ให้ดูคำตอบของStéphane Chazelasซึ่งเพิ่มวิธีการหลบหนีที่ฉลาด