Regex: จับคู่กับการเกิดขึ้นครั้งแรกของตัวละคร


356

ฉันกำลังมองหารูปแบบที่ตรงกับทุกอย่างจนกระทั่งเกิดขึ้นครั้งแรกของตัวละครที่เฉพาะเจาะจงพูดเป็น ";" - เป็นอัฒภาค

ฉันเขียนสิ่งนี้:

/^(.*);/

แต่จริงๆแล้วมันตรงกับทุกอย่าง (รวมถึงเครื่องหมายอัฒภาค) จนกระทั่งเกิดอัฒภาคครั้งสุดท้าย


65
/^(.*?);/ควรใช้งานได้ (เรียกว่าไม่โลภ ) แต่คำตอบที่ได้รับ[^;]*จะดีกว่า
ปาสกาล

คุณจะเลือกทุกอย่างอย่างไรหลังจากอัฒภาคและไม่ใช่อัฒภาค
มูฮัมหมัดอูเมอร์

เห็นผลงานนี้\w+(?!([^]+;)|;)แต่ไม่ได้เพราะอะไร .+(?!([^]+;)|;)
มูฮัมหมัดอูเมอร์

1
ปาสกาลคุณควรเขียนสิ่งนั้นเพื่อเป็นคำตอบ!
Sean Kendle

@Pascal นี้เหมาะสำหรับเป็นคำตอบ! ขอบคุณ!
neverMind9

คำตอบ:


503

คุณต้องการ

/[^;]*/

[^;]เป็นตัวละครคลาสมันตรงกับทุกอย่าง แต่อัฒภาค

วิธีอ้างอิงperlremanpage:

คุณสามารถระบุคลาสตัวละครโดยใส่รายชื่อตัวละครใน [] ซึ่งจะจับคู่ตัวละครจากรายการ หากอักขระตัวแรกหลัง "[" คือ "^" คลาสจะจับคู่อักขระใด ๆ ที่ไม่อยู่ในรายการ

สิ่งนี้น่าจะใช้ได้กับภาษาส่วนใหญ่ของ regex


ส่วนที่ดีเกี่ยวกับการแก้ปัญหานี้ก็คือตรงกับจุดสิ้นสุดของบรรทัดเช่นในกรณีของฉันฉันมีfoo=bar;baz=bax;bab=bafและมันจับคู่bab=bafแม้ไม่มี;สิ่งที่ฉันต้องการ ไม่แน่ใจว่าทำไมมันถึงใช้งานได้ถ้า spec บอกว่าตรงกับทุกอย่าง แต่เป็นสัญลักษณ์เป้าหมาย ...
4652

303

หากว่า;

/^(.*?);/

งาน?

?เป็นผู้ประกอบการขี้เกียจดังนั้นคว้า regex ;น้อยที่สุดเท่าที่เป็นไปได้ก่อนที่จะจับคู่


4
ใช่ แต่หลังจากการขยายไบคาร์บอเนตไปที่ Tim Toady ฉันเชื่อว่าคลาสตัวละครที่ได้รับการลุ้นรับรางวัลเนื่องจากตัวนับที่ขี้เกียจรวมถึงการย้อนกลับ +1 อยู่ดี
Amarghosh

3
น่าอ่านในหัวข้อประสิทธิภาพ: blog.stevenlevithan.com/archives/greedy-lazy-performance
Glenn Slaven

38

/^[^;]*/

[^;] พูดว่าจับคู่ทุกอย่างยกเว้นอัฒภาค วงเล็บเหลี่ยมเป็นตัวดำเนินการจับคู่ชุดโดยพื้นฐานแล้วจะจับคู่อักขระใด ๆ ในชุดของอักขระนี้^เมื่อเริ่มต้นทำให้เป็นการจับคู่ผกผันดังนั้นตรงกับสิ่งที่ไม่ได้อยู่ในชุดนี้


3
โปรดระวังว่า ^ แรกในคำตอบนี้ให้ความหมายที่แตกต่างอย่างสิ้นเชิงกับ regex: ทำให้นิพจน์ทั่วไปค้นหาเฉพาะการจับคู่เริ่มต้นจากจุดเริ่มต้นของสตริง ในกรณีนี้จะไม่มีประสิทธิภาพหากคุณใช้นิพจน์ปกติเพียงครั้งเดียว หากคุณต้องการค้นหาการแข่งขันหลายรายการภายในสตริงเดียว ^ แรกจะต้องไป
Dan Breslau

4
เขาบอกว่าเขาต้องการจับคู่ทุกอย่างจนเกิดเซมิโคลอนครั้งแรกดังนั้นฉันจึงคิดว่าเขาหมายถึงตั้งแต่เริ่มต้นของสตริง
Glenn Slaven



8

ข้อความตัวอย่าง:

"this is a test sentence; to prove this regex; that is g;iven below"

หากตัวอย่างเรามีข้อความตัวอย่างข้างต้น regex /(.*?\;)/จะให้ทุกอย่างแก่คุณจนกว่าจะมีเครื่องหมายอัฒภาค ( ;) เกิดขึ้นเป็นครั้งแรกรวมถึงเครื่องหมายอัฒภาค:"this is a test sentence;"


3
มันไม่จำเป็นที่จะต้องหลบหนี;เพราะมันไม่ได้เป็นอักขระพิเศษ regex ()ไม่จำเป็นต้องจัดกลุ่มเช่นกัน คุณสามารถไปกับ/.*?;/
Aliaksei Kliuchnikau

1
ใช่คุณพูดถูก การหลบหนีนั้นเหมือน "ปลอดภัยกว่าขอโทษ"
poncius

2
นี่คือคำตอบที่ฉันต้องการ ดังนั้น ? ทำให้การแข่งขันจบลงในการปรากฏตัวครั้งแรก? ชื่อนี้คืออะไร (เรียกว่า) คุณสมบัติของ regex?
Parziphal

1
@Parziphal ?อักขระทำให้การจับคู่ขี้เกียจ (การจับคู่ให้น้อยที่สุดเท่าที่จะทำได้) คิดว่าตัวอักษรที่จับคู่ regex จนถึงเซมิโคลอนแรกแล้วมันจะไม่ไปไกลกว่านี้เพราะมันยอมแพ้ (ขี้เกียจ;))
derekantrican

5

นี่ไม่ใช่วิธีการแก้ปัญหา regex แต่สิ่งที่ง่ายพอสำหรับคำอธิบายปัญหาของคุณ เพียงแค่แบ่งสตริงของคุณและรับรายการแรกจากอาร์เรย์ของคุณ

$str = "match everything until first ; blah ; blah end ";
$s = explode(";",$str,2);
print $s[0];

เอาท์พุต

$ php test.php
match everything until first

5

สิ่งนี้มีประโยชน์มากสำหรับฉันเนื่องจากฉันพยายามหาวิธีจับคู่อักขระทั้งหมดในแท็ก xml รวมถึงคุณลักษณะ ฉันพบปัญหา "ตรงกับทุกสิ่งจนจบ" ด้วย:

/<simpleChoice.*>/

แต่สามารถแก้ไขปัญหาได้ด้วย:

/<simpleChoice[^>]*>/

หลังจากอ่านโพสต์นี้ ขอบคุณทุกคน


1
ฉันพบว่ามันเป็นวิธีที่มีประสิทธิภาพมากขึ้นในการแยกวิเคราะห์จริง (แต่ละภาษาหรือกรอบมีชั้นเรียนของตัวเอง) html / xml เนื่องจากรูปแบบของเครื่องมัน regex เป็นภาษาธรรมชาติ
Leon Fedotov

1
ดี ฉันใช้สิ่งนี้เพื่อแก้ไขเอกสาร xml ด้วยข้อผิดพลาดทางไวยากรณ์ใน<!DOCTYPE>แท็ก เนื่องจาก parser ไม่สามารถจัดการได้
Martin Schneider

5

สิ่งนี้จะจับคู่กับการเกิดขึ้นครั้งแรกเฉพาะในแต่ละสายและจะละเว้นการเกิดขึ้นในภายหลัง

/^([^;]*);*/

3

"/^([^\/]*)\/$/" ทำงานสำหรับฉันเพื่อรับเฉพาะ "โฟลเดอร์" ด้านบนจากอาร์เรย์เช่น:

a/   <- this
a/b/
c/   <- this
c/d/
/d/e/
f/   <- this

2

เสียใจจริงๆที่ไม่มีใครให้คำตอบที่ถูกต้องกับคุณ ....

ใน regex ทำให้มันไม่โลภ โดยค่าเริ่มต้น regex จะจับคู่มากที่สุดเท่าที่จะทำได้ (โลภ)

เพียงเพิ่ม และมันจะไม่โลภและจับคู่น้อยที่สุด!

ขอให้โชคดีหวังว่าจะช่วยได้


3
สิ่งนี้ขึ้นอยู่กับการใช้งาน regex จริงและไม่ใช่ทุกการใช้งานที่มีโหมดไม่โลภ
karatedog

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