Regex เพื่อจับคู่สตริงที่มีสองชื่อในลำดับใด ๆ


180

ฉันต้องการตรรกะและใน regex

สิ่งที่ต้องการ

แจ็คและเจมส์

เห็นด้วยกับสตริงดังต่อไปนี้

  • ' แจ็คสวัสดีนี่คือเจมส์ '

  • 'สวัสดีเจมส์นี่คือแจ็ค '


1
เป็นไปได้ที่ซ้ำกัน: mulitple-words-in-any-order-using-regex
Anderson Green

@AndersonGreen คำถามถูกล็อคก่อนกำหนด คำตอบจะเป็นรุนแรงขาดการแก้ปัญหาเหล่านี้จะไม่ทำงานตั้งแต่ regex ส่วนใหญ่ไม่รู้จักLookAroundและโหมดปริมาณ ฉันเชื่อว่ามีตัวนับจำนวนณ จุดของคำถามที่ถูกถาม
XPMai

คำตอบ:


261

คุณสามารถทำการตรวจสอบโดยใช้lookarounds :

^(?=.*\bjack\b)(?=.*\bjames\b).*$

ทดสอบมัน

วิธีนี้มีข้อดีที่คุณสามารถระบุหลายเงื่อนไขได้อย่างง่ายดาย

^(?=.*\bjack\b)(?=.*\bjames\b)(?=.*\bjason\b)(?=.*\bjules\b).*$

18
ใครบางคนจะอธิบายด้วยรายละเอียดอีกเล็กน้อยว่าตัวอย่างนี้ทำงานอย่างไร
bjmc

2
vimไวยากรณ์: ^\(.*\<jack\>\)\@=\(.*\<james\>\@=\).*$หรือ\v^(.*<jack>)@=(.*<james>)@=.*$
mykhal

ไม่มีใครรู้ว่าทำไมสิ่งนี้ถึงแตก (อย่างน้อยใน JavaScript) เมื่อฉันพยายามค้นหาสตริงที่ขึ้นต้นด้วย '#' ^(?=.*\b#friday\b)(?=.*\b#tgif\b).*$ไม่สามารถจับคู่ได้blah #tgif blah #friday blahแต่ใช้^(?=.*\bfriday\b)(?=.*\btgif\b).*$งานได้ดี
btleffler

2
ที่\bนี่หมายความว่าอย่างไร
VarunAgw

1
@VarunAgw ขอบเขตของคำ regular-expressions.info/refwordboundaries.html
Alin Purcaru

106

ลอง:

james.*jack

หากคุณต้องการทั้งสองอย่างในเวลาเดียวกันorพวกเขา:

james.*jack|jack.*james

1
คำตอบที่ยอมรับใช้งานได้ มันทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน สำหรับการค้นหารหัสใน Visual Studio 'ค้นหาผลลัพธ์'
โยเกิร์ต The Wise

1
อันนี้เหมาะกับฉันและเข้าใจง่ายกว่าคำตอบที่ยอมรับ!
Kumar Manish

1
ฉันต้องการวิธีแก้ปัญหาที่มีเพียงสองชื่อเท่านั้นที่ตรงกันดังนั้นคำตอบนี้กระชับสำหรับกรณีนี้มากขึ้น แต่คำตอบที่ได้รับการยอมรับมีความกระชับมากกว่า 2 เนื่องจากจำนวน "หรือ" เพิ่มขึ้นอย่างมีนัยสำคัญ สำหรับ 3 ชื่อจะมี 6 "หรือ" s, 4 ชื่อจะเป็น 24 "หรือ" s ฯลฯ
WileCau

james.*?jack|jack.*?jamesฉันจะแนะนำที่จะทำให้มันขี้เกียจ ซึ่งจะช่วยในตำราขนาดใหญ่
Jekis

42

คำอธิบายของคำสั่งที่ฉันจะเขียน : -

. หมายถึงตัวอักษรตัวเลขใด ๆ สามารถเข้ามาแทนที่

* หมายถึงสิ่งที่เกิดขึ้นเป็นศูนย์หรือมากกว่านั้นที่เขียนไว้ก่อนหน้านี้

|หมายถึง'หรือ'

ดังนั้น,

james.*jack

จะค้นหาjames จากนั้นจึงมีจำนวนอักขระจนกระทั่งjackถึง

เนื่องจากคุณต้องการอย่างใดอย่างหนึ่งjack.*jamesหรือjames.*jack

ดังนั้นคำสั่ง :

jack.*james|james.*jack

7
ในฐานะที่เป็นบันทึกย่อ - คุณสามารถแก้ไข @ icyrock คำตอบของคุณ (ซึ่งเป็นเช่นเดียวกับคุณเมื่อ 6 ปีก่อน) คำอธิบายของคุณมีประโยชน์มาก
WoJ

2
ขอบคุณสำหรับคำตอบนี้ แต่ฉันรู้สึกว่าจำเป็นต้องชี้ให้เห็นว่าในการค้นหา VSCode แจ็คคำตอบของคุณ * james | แจ็ค james. *จะใช้ช่องว่างระหว่าง '|' (หรือ) สัญลักษณ์เข้าสู่การพิจารณาในระหว่างการค้นหา แจ็ค. * james | james. * แจ็คทำงานได้และไม่ได้มองหาช่องว่าง
jgritten

2
หาก $ _explanation === "ยอดเยี่ยม" จากนั้นส่งคืน $ THUMBS_UP ENDIF;
Syed Aqeel



2

Vim มีตัวดำเนินการสาขา\&ที่มีประโยชน์เมื่อค้นหาบรรทัดที่มีชุดของคำในลำดับใด ๆ ยิ่งกว่านั้นการขยายชุดคำที่ต้องการนั้นเป็นเรื่องเล็กน้อย

ตัวอย่างเช่น,

/.*jack\&.*james

จะจับคู่บรรทัดที่มีjackและjamesในลำดับใด ๆ

ดูคำตอบนี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้งาน ฉันไม่ทราบถึงรสชาติอื่น ๆ ของ regex ที่ใช้การแตกแขนง; ผู้ประกอบการไม่ได้รับการบันทึกไว้ในรายการ wikipedia ปกติ


2

วิธีที่ 1: หนึ่งjackและหนึ่งjames

ในกรณีที่สองjackหรือสองjamesจะไม่ได้รับอนุญาตเพียงคนเดียวjackและหนึ่งjamesจะถูกต้องเราจะสามารถออกแบบการแสดงออกคล้ายกับ:

^(?!.*\bjack\b.*\bjack\b)(?!.*\bjames\b.*\bjames\b)(?=.*\bjames\b)(?=.*\bjack\b).*$

ที่นี่เราจะแยกอินสแตนซ์ของคู่เหล่านั้นโดยใช้ข้อความเหล่านี้

(?!.*\bjack\b.*\bjack\b)

และ,

(?!.*\bjames\b.*\bjames\b)

สาธิต RegEx 1

เรายังสามารถทำให้มันง่ายขึ้น

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$

ตัวอย่าง RegEx 2


หากคุณต้องการที่จะลดความซับซ้อน / การแก้ไข / การสำรวจการแสดงออกก็ถูกอธิบายอยู่ด้านบนขวาของแผงregex101.com หากคุณต้องการคุณยังสามารถดูในลิงค์นี้ว่ามันจะตรงกับอินพุตตัวอย่างบางส่วนได้อย่างไร


วงจร RegEx

jex.imเห็นภาพการแสดงออกปกติ:

ป้อนคำอธิบายรูปภาพที่นี่

ทดสอบ

const regex = /^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$/gm;
const str = `hi jack here is james
hi james here is jack
hi james jack here is jack james
hi jack james here is james jack
hi jack jack here is jack james
hi james james here is james jack
hi jack jack jack here is james
`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}


วิธีที่ 2: หนึ่งjackและหนึ่งjamesในลำดับที่เฉพาะเจาะจง

มันสามารถถูกออกแบบสำหรับครั้งแรกที่jamesผ่านjackมาคล้ายกับคนต่อไปนี้:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b.*\bjack\b).*$

สาธิต RegEx 3

และในทางกลับกัน:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjack\b.*\bjames\b).*$

สาธิต RegEx 4


0

คุณสามารถทำให้การใช้ regex ของปริมาณคุณลักษณะตั้งแต่lookaroundอาจจะไม่ได้รับการสนับสนุนตลอดเวลา

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