Regex จับคู่อักขระทั้งหมดระหว่างสองสาย


434

ตัวอย่าง: "นี่เป็นเพียงประโยคง่ายๆ \ n"

ฉันต้องการจับคู่อักขระทุกตัวระหว่าง "นี่คือ" และ "ประโยค" ตัวแบ่งบรรทัดควรถูกละเว้น ฉันไม่สามารถหาไวยากรณ์ที่ถูกต้องได้


11
คุณอาจต้องการระบุสภาพแวดล้อมที่คุณใช้ Regex ซึ่งอาจมีความแตกต่างกันไปขึ้นอยู่กับว่าคุณหมายถึงอะไรโดยแบ่งบรรทัด "ละเว้น"
Andrew Barber

คำตอบ:


646

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

(?<=This is)(.*)(?=sentence)

Regexr

ผมใช้ lookbehind (?<=)และมองไปข้างหน้า(?=)เพื่อที่ว่า "นี่คือการ" และ "ประโยคที่ว่า" ไม่ได้รวมอยู่ในการแข่งขัน This is(.*)sentenceแต่เรื่องนี้ขึ้นอยู่กับกรณีการใช้งานของคุณคุณยังสามารถเพียงแค่เขียน

สิ่งสำคัญที่นี่คือคุณเปิดใช้งานโหมด "dotall" ของโปรแกรม regex ของคุณเพื่อให้การ.จับคู่ขึ้นบรรทัดใหม่ แต่วิธีที่คุณทำสิ่งนี้ขึ้นอยู่กับเอ็นจิ้น regex ของคุณ

สิ่งต่อไปคือถ้าคุณใช้หรือ.* .*?คนแรกคือโลภและจะจับคู่จนถึง "ประโยค" สุดท้ายในสายของคุณคนที่สองขี้เกียจและจะจับคู่จนถึง "ประโยค" ถัดไปในสายของคุณ

ปรับปรุง

Regexr

This is(?s)(.*)sentence

ที่ (?) เปิดตัวปรับแต่ง dotall ทำให้การ.จับคู่อักขระขึ้นบรรทัดใหม่

อัปเดต 2:

(?<=is \()(.*?)(?=\s*\))

กำลังจับคู่ตัวอย่างของคุณ "นี่คือ (ประโยคง่าย ๆ )" ดูที่นี่ในRegexr


@ คริสขอโทษฉันต้องมองหามัน ฉันเข้าใจถูกต้องและThis is(?s)(.*)sentenceจะทำงานหรือไม่
stema

@stema: ใช่ว่าควรจะเปิดใช้งานโหมด "dot all" ภายใต้ไลบรารี regex ส่วนใหญ่
tchrist

1
ส่วนใหญ่จะแก้ไขปัญหาของฉัน แต่ฉันจะรวมอักขระช่องว่างในรูปแบบของฉันได้อย่างไร ฉันลองต่อไปนี้: "(. *?) ())" เพื่อให้ตรงกับ ")" ในตอนท้ายของลำดับ แต่มันไม่ทำงาน
0xbadf00d

28
เพียงหนึ่งบันทึก - regexr บอกว่าตอนนี้ที่ lookbehind ไม่ได้รับการสนับสนุนใน javascript
Kovo

2
มีวิธีจัดการกับอินสแตนซ์ซ้ำของการแบ่งนี้ในบล็อกข้อความหรือไม่? ตัวอย่างสำหรับ: "นี่เป็นเพียงประโยคง่ายๆ \ n นี่คือบางสิ่งเพิ่มเติมนี่เป็นเพียง \ na ประโยคง่ายๆและนี่คือสิ่งอื่น ๆ อีกมากมายนี่เป็นเพียงประโยคง่ายๆ \ n" ขณะนี้มันตรงกับสตริงทั้งหมดมากกว่าแต่ละตัวอย่าง
jzadra

181

Lazy Quantifier ที่ต้องการ

การกู้คืนคำถามนี้เนื่องจาก regex ในคำตอบที่ยอมรับนั้นดูเหมือนจะไม่ถูกต้องสำหรับฉัน ทำไม? เพราะ

(?<=This is)(.*)(?=sentence)

จะตรงกับmy first sentence. This is my secondในThis is my first sentence. This is my second sentence.

ดูการสาธิต

คุณต้องการตัวบอกปริมาณที่ขี้เกียจระหว่างสอง lookarounds การเพิ่ม?ดาวทำให้ขี้เกียจ

สิ่งนี้ตรงกับสิ่งที่คุณต้องการ:

(?<=This is).*?(?=sentence)

ดูการสาธิต ฉันลบกลุ่มจับภาพซึ่งไม่ต้องการ

โหมด DOTALL เพื่อจับคู่ข้ามตัวแบ่งบรรทัด

โปรดทราบว่าในการสาธิตจะมีการตั้งค่า "โหมดการจับคู่จุดแบ่งบรรทัด" (aka) dot-all (ดูวิธีเปิด DOTALL ในภาษาต่างๆ ) ในรสชาติที่หลากหลายของ regex คุณสามารถตั้งค่าด้วยโมดิฟายเออร์ออนไลน์(?s)เปลี่ยนนิพจน์เป็น:

(?s)(?<=This is).*?(?=sentence)

การอ้างอิง


คุณถูกต้องเกี่ยวกับกลุ่มการจับภาพ ไม่รู้ว่าทำไมฉันถึงทำแบบนี้ แต่ความแตกต่างระหว่าง.*และ.*?ยังอธิบายในคำตอบของฉัน (ย่อหน้าก่อนหน้า "อัพเดต") ดังนั้นฉันไม่คิดว่าคำตอบของฉันไม่ถูกต้อง
stema

2
@stema ขออภัยเกี่ยวกับ nitpicking ในขณะที่แล่นผ่านคำตอบของคุณเมื่อวานนี้ซึ่งเป็นคำเดียวที่ทำให้ฉันกระตุก :) ฉันลดบรรทัดแรกจากis incorrectเป็นdoesn't seem quite correct to me... หวังว่าจะไม่ทำให้คุณกระตุกอาจเป็นเพียงความแตกต่างของการรับรู้เกี่ยวกับสิ่งที่ regex สำหรับคำตอบที่มีอัตราการเข้าชมสูงควรเป็นอย่างไร
zx81

39

ลองใช้This is[\s\S]*sentenceงานจาวาสคริปต์


วิธีทำการค้นหาแบบสันหลังยาวในลักษณะนี้
AGamePlayer

4
@AwQiruiGuo เช่นเดียวกับข้างต้น [\s\S]*?(เรียกอีกอย่างว่า: ไวลด์การ์ดที่ไม่ใช่โลภ)
phil294


13

ใช้สิ่งนี้: (?<=beginningstringname)(.*\n?)(?=endstringname)


ไม่ทราบว่าทำไมการลงคะแนนทั้งหมดนี้จะช่วยให้มีการแบ่ง 0-1 บรรทัดและการแบ่งบรรทัดจะต้องมาก่อนendstringname
OGHaza

ฉันพบว่ามีประโยชน์ในการลบจุดเริ่มต้นของสายการบันทึก (การประทับเวลา ฯลฯ ) ฉันใช้บรรทัดใหม่สำหรับสตริงเริ่มต้นและ "at" สำหรับสตริงสุดท้าย
Stan

2

ในกรณีที่ทุกคนกำลังมองหาตัวอย่างของสิ่งนี้ภายในบริบทของเจนกินส์ มันแยกวิเคราะห์ build.log และหากพบการแข่งขันมันจะล้มเหลวในการสร้างด้วยการจับคู่

import java.util.regex.Matcher;
import java.util.regex.Pattern;

node{    
    stage("parse"){
        def file = readFile 'build.log'

        def regex = ~"(?s)(firstStringToUse(.*)secondStringToUse)"
        Matcher match = regex.matcher(file)
        match.find() {
            capturedText = match.group(1)
            error(capturedText)
        }
    }
}


0

ข้อความประเสริฐ 3x

ในข้อความประเสริฐคุณเพียงเขียนคำสองคำที่คุณสนใจเก็บไว้ในกรณีของคุณ

"นี่คือ" และ "ประโยค"

และคุณเขียน. * ในระหว่าง

กล่าวคือ This is .* sentence

และสิ่งนี้ควรทำอย่างไรดี


ไม่แน่ใจว่าคำถามเกี่ยวกับวิธีการทำเช่นนี้ใน Sublime Text แต่ส่วนใหญ่จะทำงานใน Sublime Text มันไม่ทำงานเมื่อเกิดการขัดข้องระหว่าง "นี่คือ" และ "ประโยค" นอกจากนี้ข้อความประเสริฐยังเลือก "นี่คือ" และ "ประโยค" แทนที่จะเป็นเพียงข้อความระหว่างสองสตริง
Dylan Kinnett

0

นี่คือวิธีที่ฉันทำ: มัน
ง่ายกว่าที่ฉันจะคิดออก regex เฉพาะที่จำเป็น

int indexPictureData = result.IndexOf("-PictureData:");
int indexIdentity = result.IndexOf("-Identity:");
string returnValue = result.Remove(indexPictureData + 13);
returnValue = returnValue + " [bytecoderemoved] " + result.Remove(0, indexIdentity); ` 

0

สำหรับการค้นหาอย่างรวดเร็วใน VIM คุณสามารถใช้ที่พร้อมท์ Vim Control: / นี่คือ. * \ _. * ประโยค


0

ฉันลงจอดที่นี่เพื่อค้นหา regex เพื่อแปลงไวยากรณ์การพิมพ์นี้ระหว่างการพิมพ์ "string" ใน Python2 ในสคริปต์เก่าด้วย: print ("string") สำหรับ Python3 ใช้งานได้ดีมิฉะนั้นใช้ 2to3.py เพื่อการแปลงเพิ่มเติม นี่คือทางออกของฉันสำหรับคนอื่น ๆ :

ลองใช้กับ Regexr.com (ใช้งานไม่ได้ใน NP ++ ด้วยเหตุผลบางอย่าง):

find:     (?<=print)( ')(.*)(')
replace: ('$2')

สำหรับตัวแปร:

(?<=print)( )(.*)(\n)
('$2')\n

สำหรับฉลากและตัวแปร:

(?<=print)( ')(.*)(',)(.*)(\n)
('$2',$4)\n

จะแทนที่การพิมพ์ "string" ทั้งหมดใน Python2 ด้วย print ("string") สำหรับ Python3 ได้อย่างไร


0

สิ่งนี้ใช้ได้สำหรับฉัน (ฉันใช้VS Code ):

สำหรับ: This is just\na simple sentence

ใช้: This .+ sentence


0

RegEx เพื่อจับคู่ทุกอย่างระหว่างสองสายโดยใช้วิธีการของ Java

List<String> results = new ArrayList<>(); //For storing results
String example = "Code will save the world";

Let 's รูปแบบการใช้งานและ Matcher วัตถุที่จะใช้ RegEx (. ?) *

Pattern p = Pattern.compile("Code "(.*?)" world");   //java.util.regex.Pattern;
Matcher m = p.matcher(example);                      //java.util.regex.Matcher;

เนื่องจาก Matcher อาจมีมากกว่าหนึ่งคู่เราจึงต้องวนซ้ำผลลัพธ์และเก็บไว้

while(m.find()){   //Loop through all matches
   results.add(m.group()); //Get value and store in collection.
}

ตัวอย่างนี้จะมีเพียงคำว่า"จะบันทึก"แต่ในข้อความที่ใหญ่กว่านั้นก็อาจจะพบการจับคู่เพิ่มเติม

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