นิพจน์ทั่วไปจากโมดูล re รองรับขอบเขตคำ (\ b) หรือไม่


102

ในขณะที่พยายามเรียนรู้เพิ่มเติมเล็กน้อยเกี่ยวกับนิพจน์ทั่วไปบทช่วยสอนแนะนำว่าคุณสามารถใช้\bเพื่อจับคู่ขอบเขตคำได้ อย่างไรก็ตามตัวอย่างต่อไปนี้ในตัวแปล Python ไม่ทำงานตามที่คาดไว้:

>>> x = 'one two three'
>>> y = re.search("\btwo\b", x)

มันควรจะได้รับวัตถุแข่งขันหากมีสิ่งใดถูกจับคู่ Noneแต่มันเป็น

คือ\bการแสดงออกไม่ได้รับการสนับสนุนในหลามหรือฉันใช้มันผิดหรือเปล่า?


31
สิ่งนี้จะได้ผล:re.search(r"\btwo\b", x)
Bolo

5
ทำไมคุณไม่ใช้สตริง "ดิบ" r"\btwo\b"เหรอ?
ล็อ

3
คนกำลังมักจะสับสน\bเกี่ยวกับ
tchrist

ใช่ Python ต้องการคุณเพียงแค่ต้องใช้สตริงดิบr'\b'เพื่อให้อักขระถูกหลีกเลี่ยง (หรือมิฉะนั้นก็หนีสองครั้ง\\bซึ่งก็คือ yukky)
smci

คำตอบ:


86

ทำไมคุณไม่ลอง

word = 'two'
re.compile(r'\b%s\b' % word, re.I)

เอาท์พุต:

>>> word = 'two'
>>> k = re.compile(r'\b%s\b' % word, re.I)
>>> x = 'one two three'
>>> y = k.search( x)
>>> y
<_sre.SRE_Match object at 0x100418850>

อย่าลืมพูดถึงคุณควรใช้สตริงดิบในโค้ดของคุณ

>>> x = 'one two three'
>>> y = re.search(r"\btwo\b", x)
>>> y
<_sre.SRE_Match object at 0x100418a58>
>>> 

น่าสนใจขอบคุณสำหรับตัวอย่างการทำงาน คุณมีความเข้าใจว่าทำไมวิธีที่ฉันเลือกใช้ไม่ได้ผล? แนวทางทั้งสองควรเหมือนกันยกเว้นว่าในแนวทางของคุณคุณรวบรวมเพียงครั้งเดียว
DC

1
@darren: ดูตัวอย่างสุดท้ายของฉันที่ปรับปรุงสิ่งที่คุณทำ ฉันให้สตริงดิบเพื่อค้นหา
pyfunc

1
อาตามคำแนะนำของคุณและโบโลนั่นเป็นเพราะฉันไม่ได้ใช้สตริงดิบ ขอบคุณ!
DC

9
-1: ถอยหลัง สตริงดิบควรเป็นอันดับแรก ธุรกิจอื่น ๆ ของการสร้างนิพจน์ re ด้วยการ%แทนที่สตริงคือแทนเจนต์ที่ไม่ดีไม่เกี่ยวข้องกับคำถามเฉพาะนี้
ล็อ

2
คำตอบที่ไม่ดี รหัสใช้งานได้ แต่ไม่มีคำอธิบายใด ๆ
Aran-Fey

89

สิ่งนี้จะได้ผล: re.search(r"\btwo\b", x)

เมื่อคุณเขียน"\b"ใน Python มันจะเป็นอักขระเดี่ยว: "\x08". หลีกเลี่ยงเครื่องหมายแบ็กสแลชเช่นนี้:

"\\b"

หรือเขียนสตริงดิบดังนี้:

r"\b"

4
สิ่งนี้ช่วยฉันได้จริงๆ ... ฉันกำลังดิ้นรนกับการแสดงออกปกติของ pyspark rlike และคิดไม่ออกว่าทำไม \ b (ขอบเขตคำ) ไม่ทำงาน ขอบคุณ
jb1t

18

เพียงเพื่ออธิบายอย่างชัดเจนว่าทำไม re.search("\btwo\b", x)ไม่ทำงานนั่นเป็นเพราะ\bในสตริง Python มีชวเลขสำหรับอักขระ backspace

print("foo\bbar")
fobar

ดังนั้นรูปแบบ"\btwo\b"จึงมองหา backspace ตามด้วยtwobackspace อื่นซึ่งสตริงที่คุณค้นหาใน ( x = 'one two three') ไม่มี

ในการอนุญาตให้re.search(หรือcompile) ตีความลำดับ\bเป็นขอบเขตของคำให้หลีกเลี่ยงเครื่องหมายแบ็กสแลช ( "\\btwo\\b") หรือใช้สตริงดิบเพื่อสร้างรูปแบบของคุณ ( r"\btwo\b")


10

เอกสาร Python

https://docs.python.org/2/library/re.html#regular-expression-syntax

\ b

จับคู่สตริงว่าง แต่อยู่ที่จุดเริ่มต้นหรือตอนท้ายของคำเท่านั้น คำถูกกำหนดให้เป็นลำดับของอักขระที่เป็นตัวอักษรและตัวเลขคละกันหรือขีดล่างดังนั้นจุดสิ้นสุดของคำจะถูกระบุด้วยช่องว่างหรืออักขระที่ไม่ใช่ตัวเลขและตัวอักษรและไม่ใช่ขีดล่าง โปรดทราบว่าอย่างเป็นทางการ \ b ถูกกำหนดให้เป็นขอบเขตระหว่างอักขระ \ w และอักขระ \ W (หรือในทางกลับกัน) หรือระหว่าง \ w และจุดเริ่มต้น / จุดสิ้นสุดของสตริงดังนั้นชุดอักขระที่แน่นอนจึงถือว่าเป็นตัวเลขและตัวอักษรขึ้นอยู่กับ เกี่ยวกับค่าของแฟล็ก UNICODE และ LOCALE ตัวอย่างเช่น r '\ bfoo \ b' ตรงกับ 'foo', 'foo.', '(foo)', 'bar foo baz' แต่ไม่ใช่ 'foobar' หรือ 'foo3' ภายในช่วงอักขระ \ b ​​แสดงถึงอักขระ backspace เพื่อความเข้ากันได้กับสตริงลิเทอรัลของ Python

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