Regex: จับคู่ทุกอย่างยกเว้นรูปแบบเฉพาะ


310

ฉันต้องการ regex สามารถจับคู่ทุกอย่างแต่สตริงเริ่มต้นด้วยรูปแบบเฉพาะ (โดยเฉพาะindex.phpและสิ่งต่อไปนี้เช่นindex.php?id=2342343)


และรูปแบบเฉพาะที่คุณต้องการไม่ตรงกันคืออะไร
โดมินิกร็อดเจอร์ส

2
มีเหตุผลที่คุณไม่สามารถเทียบกับรูปแบบของคุณและไม่ทำอะไรเลยถ้าสายตรงนั้น
โทมัส Owens


@ThomasOwens: มันขึ้นอยู่กับ ขึ้นอยู่กับว่าส่วนใดของการแสดงออกที่จะถูกทำให้ไร้ผล หากการแสดงออกทั้งหมดจะถูกทำให้ไร้ผลคุณก็จะมีประเด็น ตัวอย่างเช่นหากคุณต้องการโค้ดอัพ "ถ้าสตริงไม่มี 'บรูซ' เป็นสตริงย่อยให้ทำบางสิ่งบางอย่าง" คุณต้องใช้ / Bruce / อย่างชัดเจนและวางคำคัดค้านลงในคำสั่ง if นอก regex . แต่อาจเป็นไปได้ว่าคุณต้องการคัดค้านคำสั่งย่อยบางอย่าง สมมติว่าคุณกำลังมองหาบางอย่างเช่นชื่อนามสกุลโดยที่ชื่อแรกคือบรูซและนามสกุลคือทุกอย่างยกเว้น XYZ โดยที่ XYZ เป็นนามสกุลของผู้มีชื่อเสียงบางคนชื่อบรูซ
mathheadinclouds

คำตอบ:


250

ไม่ได้เป็นผู้เชี่ยวชาญ regexp แต่ฉันคิดว่าคุณสามารถใช้ lookahead เชิงลบจากการเริ่มต้นเช่นไม่ควรตรงกับสิ่งที่เริ่มต้นด้วย^(?!foo).*$foo


7
ด้วย grep ใช้ -P เพื่อเปิดใช้งาน lookahead
Seppo Enarvi

หากไม่ตรงกับ "foo" หรือ "bar" เป็นพฤติกรรมที่คุณต้องการให้ตรวจสอบคำตอบนี้: stackoverflow.com/a/2404330/874824
dave_k_smith

15
คำตอบนี้ผิดการทดสอบด่วนแสดงให้เห็นว่า ฉันคิดว่าสิ่งที่คุณหมายถึงคือ^((?!foo).)*$( stackoverflow.com/a/406408/3964381 )
gilad mayani

4
คุณช่วยอธิบายสัญลักษณ์ที่คุณใช้และทำไมคุณถึงใช้มัน?
rotimi ที่ดีที่สุด

339

Regex: จับคู่ทุกอย่างแต่ :

  • สตริงที่เริ่มต้นด้วยรูปแบบที่เฉพาะเจาะจง (เช่นใด - ที่ว่างเปล่าเกินไป - สตริงไม่ได้เริ่มต้นด้วยfoo):
  • สตริงลงท้ายด้วยรูปแบบที่เฉพาะเจาะจง (พูดว่าไม่มีworld.ที่สิ้นสุด):
  • สตริงที่มีข้อความที่ระบุ (พูดไม่ตรงกับสตริงมีfoo) (ไม่ POSIX patern ตามขออภัย):
  • สตริงที่มีเฉพาะของตัวละคร (พูดหลีกเลี่ยงการจับคู่สตริงที่มี|สัญลักษณ์):
  • สตริงเท่ากับบางสตริง (พูดไม่เท่ากับfoo):
  • ลำดับตัวอักษร :
    • PCRE (ตรงกับข้อความใดก็ได้cat): /cat(*SKIP)(*FAIL)|[^c]*(?:c(?!at)[^c]*)*/iหรือ/cat(*SKIP)(*FAIL)|(?:(?!cat).)+/is
    • เอ็นจิ้นอื่นที่อนุญาตให้ใช้ lookarounds: (cat)|[^c]*(?:c(?!at)[^c]*)*(หรือ(?s)(cat)|(?:(?!cat).)*, หรือ(cat)|[^c]+(?:c(?!at)[^c]*)*|(?:c(?!at)[^c]*)+[^c]*) จากนั้นตรวจสอบด้วยภาษาหมายถึง: หากจับคู่กลุ่ม 1 ไม่ใช่สิ่งที่เราต้องการมิฉะนั้นคว้าค่าการจับคู่หากไม่ว่างเปล่า
  • ตัวเดียวหรือบางชุดของตัวอักษร :

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

Anchor note : ในหลาย ๆ ภาษาให้ใช้\Aเพื่อกำหนดจุดเริ่มต้นของสตริงที่ไม่คลุมเครือและ\z(ใน Python คือ\Zใน JavaScript $คือ OK) เพื่อกำหนดจุดสิ้นสุดของสตริง

Dot หมายเหตุ : ในรสชาติมาก ( แต่ไม่ POSIX, TRE, TCL) .ตรงกับถ่านใด ๆแต่การขึ้นบรรทัดใหม่ถ่าน ตรวจสอบให้แน่ใจว่าคุณใช้ตัวดัดแปลง DOTALL ที่สอดคล้องกัน ( /sใน PCRE / Boost / .NET / Python / Java และ/mRuby) เพื่อ.ให้ตรงกับอักขระใด ๆ รวมถึงการขึ้นบรรทัดใหม่

บันทึกทับขวา : ในภาษาที่คุณมีการประกาศรูปแบบกับสตริง C ช่วยให้ลำดับหนี (เช่น\nสำหรับการขึ้นบรรทัดใหม่), คุณต้องดับเบิล backslashes หนีตัวอักษรพิเศษเพื่อให้เครื่องยนต์สามารถรักษาพวกเขาเป็นตัวละครตัวอักษร (เช่นใน Java world\.จะ ประกาศให้เป็น"world\\."หรือใช้ตัวอักษรชั้นเรียน: "world[.]") ใช้ตัวอักษรของสตริงดิบ (งูใหญ่r'\bworld\b'), C # คำต่อคำอักษรของสตริง@"world\."หรือสตริง slashy / regex /world\./ตัวอักษรสัญลักษณ์เช่น


ยอดเยี่ยมเขียนขึ้น! สำหรับกรณีของ "สตริง (ไม่) เท่ากับบางสตริง" ตัวอย่างเช่น^(?!foo$)ทำไมเครื่องหมายดอลลาร์ต้องอยู่ในวงเล็บเพื่อให้นิพจน์ทำงานได้ ฉันคาดหวังว่า^(?!foo)$จะให้ผลลัพธ์เดียวกัน แต่ไม่ได้
ฮัมฟรีส์

3
@GrantHumphries: เมื่อ$สมออยู่ภายใน lookahead มันเป็นส่วนหนึ่งของเงื่อนไขที่เป็นส่วนหนึ่งของที่ยืนยันเป็นศูนย์ที่มีความกว้าง ถ้ามันอยู่ข้างนอกเหมือนข้างใน^(?!foo)$มันจะเป็นส่วนหนึ่งของรูปแบบการบริโภคที่ต้องการจุดสิ้นสุดของสตริงหลังจากเริ่มต้นของสตริงทำให้การลบ lookahead เชิงลบไม่เกี่ยวข้องเนื่องจากมันจะกลับมาจริงเสมอ(ไม่มีข้อความใด ๆ หลังจากสิ้นสุดของสตริง ให้นับประสาfoo) ดังนั้นการ^(?!foo$)จับคู่เริ่มต้นของสตริงที่ไม่ได้ตามด้วยfooที่ตามด้วยปลายสาย ^(?!foo)$ตรงกับสตริงว่าง
Wiktor Stribiżew

@ robots.txt โปรดลบความคิดเห็นเหล่านี้ คุณกำลังถามคำถาม XY คลาสของตัวละครนั้นมีจุดประสงค์เพื่อจับคู่ตัวอักษรเดียวไม่มีวิธีกำหนดลำดับตัวอักษรกับพวกเขา คุณอาจจะเพียงแค่หา substring ระหว่างจุดเริ่มต้นของสตริงและเกิดขึ้นครั้งแรกของcotหรือและลบการแข่งขันเช่นlan regex.replace(myString, "^.*?(?:cot|lan)\s*", "")
Wiktor Stribiżew

เรียน Wiktor คุณได้ปิดคำถามของฉัน แต่คำตอบที่เชื่อมโยงของคุณล้มเหลว ฉันได้อัปเดตคำถามของฉันstackoverflow.com/questions/60004380/…
MonsterMMORPG

ตัวอย่างเช่นคำตอบที่เชื่อมโยงของคุณล้มเหลวในตัวอย่างนี้ "ไอเอ็นจีแพคเกจ <! - และหน้าเว็บ <! - asdasasdas -> บรรณาธิการตอนนี้ใช้ -> Lorem Ipsum"
MonsterMMORPG

259

คุณสามารถใส่ a ^ในส่วนเริ่มต้นของชุดอักขระเพื่อจับคู่อะไรก็ได้ยกเว้นอักขระเหล่านั้น

[^=]*

จะจับคู่ทุกอย่าง แต่ =


55
มันเป็นความจริง แต่มันจะประมวลผลตัวละครทีละตัว หากคุณต้องการแยกลำดับของอักขระสองตัวขึ้นไปคุณต้องใช้ lookahead เชิงลบเหมือนที่ผู้ตอบคนอื่นพูด
อลันมัวร์

โซลูชั่นที่สมบูรณ์แบบ tu ลบตัวละครที่ไม่พึงประสงค์ใด ๆแต่ในรูปแบบ ขอบคุณ
Sirmyself

@Alan "... คุณต้องใช้ lookahead เชิงลบ ... " ไม่ถูกต้อง แต่เราไม่ควรหนักเกินไปสำหรับคุณเนื่องจาก Wiktor ไม่ได้โพสต์คำตอบของเขา - ซึ่งแสดงว่าทำไม - จนถึงปี 2016
Cary Swoveland

6

เพียงแค่จับคู่/^index\.php/จากนั้นปฏิเสธสิ่งที่ตรงกัน


str !~ /\Aindex\.php/บางทีเขียน
Cary Swoveland

6

ในหลาม:

>>> import re
>>> p='^(?!index\.php\?[0-9]+).*$'
>>> s1='index.php?12345'
>>> re.match(p,s1)
>>> s2='index.html?12345'
>>> re.match(p,s2)
<_sre.SRE_Match object at 0xb7d65fa8>

3
สิ่งนั้นจะปฏิเสธ "index_php" หรือ "index # php"

1

ฉันต้องสามารถ regex จะตรงกับทุกอย่างแต่ยกเว้นสตริงที่เริ่มต้นด้วย index.phpรูปแบบที่เฉพาะเจาะจง (เฉพาะ index.php และสิ่งต่อไปนี้เช่น index.php? id = 2342343)

ใช้วิธีการExec

    let match,
        arr = [],
        myRe = /([\s\S]+?)(?:index\.php\?id.+)/g;

    var str = 'http://regular-viragenia/index.php?id=2342343';

    while ((match = myRe.exec(str)) != null) {
         arr.push(match[1]);
    } 
    
    console.log(arr);

var myRe = /([\s\S]+?)(?:index\.php\?id=.+)/g;
var str = 'http://regular-viragenia/index.php?id=2342343';
var matches_array = myRe.exec(str);
console.log(matches_array[1]);

หรือการแข่งขันอื่น ๆ

let match,
            arr = [],
            myRe = /index.php\?id=((?:(?!index)[\s\S])*)/g;

        var str = 'http://regular-viragenia/index.php?id=2342343index.php?id=111index.php?id=222';

        while ((match = myRe.exec(str)) != null) {
             arr.push(match[1]);
        } 

        console.log(arr);


-13

วิธีที่จะไม่ใช้ regex:

// In PHP
0 !== strpos($string, 'index.php')

11
OP ขอ regex โดยเฉพาะ ... ฉันไม่แน่ใจว่านี่จะช่วยได้! (เขาอาจใช้grepคำสั่งในบรรทัดคำสั่งหรือ Perl / Python / ภาษาอื่น ๆ หรือคำสั่ง "Execute regex นี้สำหรับทุกบรรทัด" ในโปรแกรมแก้ไขข้อความ ฯลฯ ... )
rinogo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.