ตัวอย่างเช่น regex นี้
(.*)<FooBar>
จะจับคู่:
abcde<FooBar>
แต่ฉันจะทำให้ตรงกับหลายบรรทัดได้อย่างไร
abcde
fghij<FooBar>
ตัวอย่างเช่น regex นี้
(.*)<FooBar>
จะจับคู่:
abcde<FooBar>
แต่ฉันจะทำให้ตรงกับหลายบรรทัดได้อย่างไร
abcde
fghij<FooBar>
คำตอบ:
ขึ้นอยู่กับภาษา แต่ควรมีตัวแก้ไขที่คุณสามารถเพิ่มลงในรูปแบบ regex ใน PHP มันคือ:
/(.*)<FooBar>/s
sตอนท้ายทำให้เกิดจุดเพื่อให้ตรงกับทุกตัวอักษรรวมถึงการขึ้นบรรทัดใหม่
sตัวปรับแต่ง แต่ให้ทำ[^]*เพื่อผลเหมือนกัน
mตัวดัดแปลง
ลองสิ่งนี้:
((.|\n)*)<FooBar>
มันเป็นพื้นว่า "ตัวละครหรือขึ้นบรรทัดใหม่" ซ้ำแล้วซ้ำอีกเป็นศูนย์หรือมากกว่าครั้ง
((.|\n|\r)*)<FooBar>
[\s\S]* (?s).*
คำถามคือ.รูปแบบสามารถจับคู่กับตัวละครใด ๆ ? คำตอบนั้นแตกต่างกันไปในแต่ละเครื่องยนต์ ความแตกต่างที่สำคัญคือไม่ว่าจะใช้รูปแบบโดยไลบรารี POSIX หรือไลบรารีที่ไม่ใช่ POSIX
หมายเหตุพิเศษเกี่ยวกับ หลัวรูปแบบ-: ไม่ถือว่าเป็นนิพจน์ทั่วไป แต่.ตรงกับอักขระที่นั่นเช่นเดียวกับเครื่องมือที่ใช้ POSIX
หมายเหตุอื่นเกี่ยวกับ MATLAB และ เสียงคู่แปด: .ตรงกับอักขระใด ๆ ตามค่าเริ่มต้น ( สาธิต ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');( tokensมีabcde\n fghijรายการ)
นอกจากนี้ในทุก การส่งเสริมregex ของไวยากรณ์เป็นจุดตรงกับตัวแบ่งบรรทัดตามค่าเริ่มต้น ไวยากรณ์ ECMAScript ของ Boost ช่วยให้คุณปิดการใช้งานด้วยregex_constants::no_mod_m( แหล่งที่มา )
ส่วน คำพยากรณ์(เป็นแบบ POSIX) ใช้nตัวเลือก ( สาธิต ):select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
เอ็นจินที่ใช้ POSIX :
เพียง.แล้วตรงกับแบ่งบรรทัดไม่จำเป็นต้องใช้การปรับเปลี่ยนใด ๆ ให้ดูทุบตี( สาธิต )
TCL( สาธิต )PostgreSQL( สาธิต )R(TRE, เอ็นจิ้นperl=TRUEพื้นฐาน R R ที่ไม่มีสำหรับฐาน R ที่มีperl=TRUEหรือสำหรับรูปแบบstringr / stringiให้ใช้ตัวดัดแปลงแบบอินไลน์) ( สาธิต ) ก็ปฏิบัติเช่นเดียวกัน (?s).
อย่างไรก็ตามเครื่องมือที่ใช้ POSIX ส่วนใหญ่จะประมวลผลบรรทัดต่อบรรทัด ดังนั้น.ไม่ตรงกับตัวแบ่งบรรทัดเพียงเพราะพวกเขาไม่อยู่ในขอบเขต นี่คือตัวอย่างบางส่วนวิธีการแทนที่:
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'( H;1h;$!d;x;slurps ไฟล์ในหน่วยความจำ) หากต้องรวมทั้งบรรทัดsed '/start_pattern/,/end_pattern/d' file(การนำออกจากจุดเริ่มต้นจะจบลงด้วยการจับคู่รวมบรรทัด) หรือsed '/start_pattern/,/end_pattern/{{//!d;};}' file(ยกเว้นการจับคู่บรรทัด) ที่สามารถนำมาพิจารณาได้perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"( -0slurps ไฟล์ทั้งหมดในหน่วยความจำ-pพิมพ์ไฟล์หลังจากใช้สคริปต์ที่กำหนดโดย-e) โปรดทราบว่าการใช้-000peจะเลื่อนไฟล์และเปิดใช้งาน 'โหมดย่อหน้า' โดยที่ Perl ใช้บรรทัดใหม่ติดต่อกัน ( \n\n) เป็นตัวคั่นเรคคอร์ดgrep -Poz '(?si)abc\K.*?(?=<Foobar>)' file- ที่นี่zช่วยให้ไฟล์ slurping, (?s)เปิดใช้งานโหมด DOTALL สำหรับ.รูปแบบ(?i)ช่วยให้กรณีโหมดตาย\Kละเว้นข้อความที่จับคู่เพื่อให้ห่างไกล*?เป็นปริมาณขี้เกียจตรงกับสถานที่ก่อน(?=<Foobar>)<Foobar>pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file( Mเปิดใช้งานไฟล์ slurping ที่นี่) หมายเหตุpcregrepเป็นทางออกที่ดีสำหรับgrepผู้ใช้Mac OSเอ็นจินที่ไม่ใช้ POSIX :
sตัวแก้ไขPCRE_DOTALL ตัวดัดแปลง : preg_match('~(.*)<Foobar>~s', $s, $m)( สาธิต )RegexOptions.Singlelineตั้งค่าสถานะ ( สาธิต ): var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;(?s)ตัวเลือกแบบอินไลน์:$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]sฟายเออร์ (หรือ(?s)อินไลน์เวอร์ชั่นเมื่อเริ่มต้น) ( สาธิต ):/(.*)<FooBar>/sre.DOTALL(หรือre.S) หรือโมดิ(?s)ฟายเออร์ ( สาธิต ): m = re.search(r"(.*)<FooBar>", s, flags=re.S)(แล้วif m:, print(m.group(1)))Pattern.DOTALLตัวดัดแปลง (หรือการ(?s)ตั้งค่าสถานะอินไลน์) ( สาธิต ):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)(?s)ตัวดัดแปลงในรูปแบบ ( สาธิต ):regex = /(?s)(.*)<FooBar>/(?s)ตัวดัดแปลง ( สาธิต ):"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }[^]หรือแก้ไขปัญหา[\d\D]/ [\w\W]/ [\s\S]( สาธิต ):s.match(/([\s\S]*)<FooBar>/)[1]std::regex) การใช้งาน[\s\S]หรือการแก้ปัญหา JS ( สาธิต ):regex rex(R"(([\s\S]*)<FooBar>)");VBA VBScript- ใช้วิธีการเช่นเดียวกับใน ([\s\S]*)<Foobar>JavaScript, ( หมายเหตุ : MultiLineคุณสมบัติของ
RegExpวัตถุบางครั้งคิดว่าเป็นตัวเลือกที่อนุญาตให้.จับคู่ข้ามตัวแบ่งบรรทัดในขณะที่ในความเป็นจริงมันจะเปลี่ยนเฉพาะ^และ$พฤติกรรมเพื่อให้ตรงกับจุดเริ่มต้น / สิ้นสุดของสายมากกว่าสตริงเช่นเดียวกับใน JS regex ) พฤติกรรม.)
ทับทิม- ใช้ตัวดัดแปลง/m MULTILINE ( สาธิต ):s[/(.*)<Foobar>/m, 1]
(?s): regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]( สาธิต )stringr/ stringiregex ที่ขับเคลื่อนด้วยเอนจิน ICU regex ใช้(?s): stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]( สาธิต )(?s)เมื่อเริ่มต้น ( สาธิต ):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)dotMatchesLineSeparatorsหรือ (ง่ายกว่า) ส่งต่อ(?s)ตัวปรับแบบอินไลน์ไปยังรูปแบบ:let rx = "(?s)(.*)<Foobar>"(?s)ทำงานได้ง่ายที่สุด แต่นี่คือวิธีการใช้งานตัวเลือก :NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];(?s)ตัวดัดแปลง ( สาธิต ): "(?s)(.*)<Foobar>"(ใน Google Spreadsheets =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>"))หมายเหตุ(?s) :
ในเอ็นจิ้นที่ไม่ใช่ POSIX ส่วนใหญ่สามารถใช้(?s)inline modifier (หรือตัวเลือกการตั้งค่าสถานะแบบฝัง) เพื่อบังคับ.ให้ตรงกับตัวแบ่งบรรทัด
หากวางไว้ที่จุดเริ่มต้นของรูปแบบ(?s)การเปลี่ยนแปลง bahavior ของทั้งหมด.ในรูปแบบ หาก(?s)ถูกวางไว้ที่ใดที่หนึ่งหลังจากการเริ่มต้นเท่านั้นที่.จะได้รับผลกระทบที่อยู่ไปทางขวาของมันเว้นแต่reนี้เป็นรูปแบบที่ส่งผ่านไปยังหลาม ใน Python reโดยไม่คำนึงถึง(?s)ตำแหน่งรูปแบบทั้งหมด.จะได้รับผลกระทบ ผลที่ได้คือหยุดใช้(?s) (?-s)กลุ่มที่แก้ไขสามารถใช้เพื่อส่งผลต่อช่วงของรูปแบบ regex ที่ระบุเท่านั้น (เช่นDelim1(?s:.*?)\nDelim2.*จะทำการ.*?จับคู่ครั้งแรกในการขึ้นบรรทัดใหม่และที่สอง.*จะตรงกับส่วนที่เหลือของบรรทัด)
POSIX note :
ในเอ็นจิน regex ที่ไม่ใช่ POSIX การจับคู่ char, [\s\S]/ [\d\D]/ [\w\W]constructs ใด ๆสามารถใช้ได้
ใน POSIX [\s\S]จะไม่จับคู่อักขระใด ๆ (เช่นใน JavaScript หรือเอนจินที่ไม่ใช่ POSIX) เนื่องจากลำดับการยกเว้น regex ไม่ได้รับการสนับสนุนภายในนิพจน์วงเล็บเหลี่ยม [\s\S]จะแยกเป็นนิพจน์วงเล็บที่ตรงกับถ่านเดียว\หรือหรือsS
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_mแฟล็กฐานสำหรับแฟล็ก regex ของพวกเขาเพื่อแสดงว่า และ arbitor คือมักจะปรับเปลี่ยนแบบอินไลน์ ที่(?-sm)(?s).*ตั้งใหม่
.ตรงกับอักขระใด ๆ ที่นั่น (รวมถึงตัวแบ่งบรรทัด) ดูการสาธิตทุบตีออนไลน์นี้
Goไว้ในคำตอบ!
หากคุณใช้การค้นหา Eclipse คุณสามารถเปิดใช้งานตัวเลือก "DOTALL" เพื่อให้ '.' จับคู่อักขระใด ๆ รวมถึงตัวคั่นบรรทัด: เพียงเพิ่ม "(? s)" ที่จุดเริ่มต้นของสตริงการค้นหาของคุณ ตัวอย่าง:
(?s).*<FooBar>
(?s)=>(?m)
ในหลายภาษาของ regex /[\S\s]*<Foobar>/จะทำในสิ่งที่คุณต้องการ แหล่ง
([\s\S]*)<FooBar>
จุดตรงกับทั้งหมดยกเว้นการขึ้นบรรทัดใหม่ (\ r \ n) ดังนั้นใช้ \ s \ S ซึ่งจะจับคู่อักขระทั้งหมด
[text rangeOfString:regEx options:NSRegularExpressionSearch]Objective-C ขอบคุณ!
<FooBar>
ในทับทิม ทับทิมคุณสามารถใช้mตัวเลือก '' (หลายบรรทัด):
/YOUR_REGEXP/m
ดูเอกสาร Regexpใน ruby-doc.org สำหรับข้อมูลเพิ่มเติม
เรายังสามารถใช้
(.*?\n)*?
เพื่อจับคู่ทุกอย่างรวมถึงการขึ้นบรรทัดใหม่โดยไม่โลภ
สิ่งนี้จะทำให้บรรทัดใหม่เป็นตัวเลือก
(.*?|\n)*?
"."โดยปกติจะไม่ตรงกับตัวแบ่งบรรทัด เอ็นจิ้น regex ส่วนใหญ่อนุญาตให้คุณเพิ่มS-flag (หรือที่เรียกว่าDOTALLและSINGLELINE) เพื่อให้"."ตรงกับบรรทัดใหม่ [\S\s]ถ้าว่าล้มเหลวคุณสามารถทำสิ่งที่ชอบ
สำหรับ Eclipse ทำงานนิพจน์ต่อไปนี้:
ฟู
jadajada Bar "
แสดงออกปกติ:
Foo[\S\s]{1,10}.*Bar*
/(.*)<FooBar>/s
s เป็นสาเหตุให้ Dot (.) จับคู่การขึ้นบรรทัดใหม่
sธงอยู่ใน PCRE เครื่องยนต์ที่สมบูรณ์แบบที่สุด (ใช้ได้ใน Perl และ PHP) PCRE มี 10 ธง (และคุณสมบัติอื่น ๆ อีกมากมาย) ในขณะที่ JavaScript มีเพียง 3 ธง ( gmi)
ในนิพจน์ทั่วไปที่ใช้ Java คุณสามารถใช้ [\s\S]
sตั้งค่าสถานะลงในรูปแบบใน Java และ JavaScript ไม่มีsแฟล็ก
โปรดทราบว่า(.|\n)*อาจมีประสิทธิภาพน้อยกว่า (ตัวอย่าง) [\s\S]*(หากภาษาของคุณรองรับการหลบหนีดังกล่าว) และกว่าการค้นหาวิธีระบุตัวแก้ไขที่ทำ ยังตรงกับบรรทัดใหม่ หรือคุณสามารถไปกับทางเลือก POSIXy [[:space:][:^space:]]*เช่น
ใช้ RegexOptions.Singleline มันเปลี่ยนความหมายของ เพื่อรวมบรรทัดใหม่
Regex.Replace (เนื้อหา, searchText, replaceText, RegexOptions.Singleline);
ใช้โมดิฟายเออร์ปรับรูปแบบ sU จะได้ค่าที่ตรงกันใน PHP
preg_match('/(.*)/sU',$content,$match);
http://dreamluverz.com/developers-tools/regex-match-all-including-new-line http://php.net/manual/en/reference.pcre.pattern.modifiers.php
ในบริบทของการใช้งานภายในภาษานิพจน์ทั่วไปจะดำเนินการกับสตริงไม่ใช่บรรทัด ดังนั้นคุณควรจะสามารถใช้ regex ได้ตามปกติโดยสมมติว่าสตริงอินพุตมีหลายบรรทัด
ในกรณีนี้ regex ที่กำหนดจะตรงกับสตริงทั้งหมดเนื่องจาก "<FooBar>" มีอยู่ ขึ้นอยู่กับข้อกำหนดเฉพาะของการใช้งาน regex ค่า $ 1 (ที่ได้รับจาก "(. *)") จะเป็น "fghij" หรือ "abcde \ nfghij" ดังที่คนอื่น ๆ กล่าวว่าการใช้งานบางอย่างช่วยให้คุณควบคุมได้ว่า "" จะตรงกับบรรทัดใหม่ให้คุณเลือก
การใช้นิพจน์ทั่วไปแบบอิงบรรทัดมักใช้สำหรับสิ่งต่าง ๆ เช่น command เช่น egrep
ฉันมีปัญหาเดียวกันและแก้ไขในอาจไม่ใช่วิธีที่ดีที่สุด แต่ใช้งานได้ ฉันแทนที่ตัวแบ่งบรรทัดทั้งหมดก่อนที่จะทำการแข่งขันที่แท้จริงของฉัน:
mystring= Regex.Replace(mystring, "\r\n", "")
ฉันกำลังจัดการ HTML ดังนั้นการขึ้นบรรทัดใหม่จึงไม่สำคัญกับฉันในกรณีนี้
ฉันลองทุกคำแนะนำข้างต้นโดยไม่มีโชคฉันใช้. Net 3.5 FYI
(\s|\S)ดูเหมือนจะทำเคล็ดลับสำหรับฉัน!
(?s)เพื่อ.จับคู่ตัวอักษรใด ๆ อย่าใช้(\s|\S)สิ่งที่จะทำให้ประสิทธิภาพลดลง
ใน Javascript คุณสามารถใช้ [^] * เพื่อค้นหาอักขระที่เป็นศูนย์ถึงไม่สิ้นสุดรวมถึงตัวแบ่งบรรทัด
$("#find_and_replace").click(function() {
var text = $("#textarea").val();
search_term = new RegExp("[^]*<Foobar>", "gi");;
replace_term = "Replacement term";
var new_text = text.replace(search_term, replace_term);
$("#textarea").val(new_text);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="find_and_replace">Find and replace</button>
<br>
<textarea ID="textarea">abcde
fghij<Foobar></textarea>
โดยทั่วไป ไม่ตรงกับบรรทัดใหม่ดังนั้นให้ลอง((.|\n)*)<foobar>
\rด้วย:((?:.|\r?\n)*)<foobar>
ฉันต้องการจับคู่เฉพาะถ้าบล็อกใน java
...
...
if(isTrue){
doAction();
}
...
...
}
ถ้าฉันใช้ regExp
if \(isTrue(.|\n)*}
มันรวมวงเล็บปีกกาปิดสำหรับบล็อกวิธีดังนั้นฉันใช้
if \(!isTrue([^}.]|\n)*}
เพื่อแยกวงเล็บปิดออกจากการแข่งขันไวด์การ์ด
บ่อยครั้งที่เราต้องแก้ไขซับสตริงด้วยคำหลักสองสามคำกระจายข้ามบรรทัดก่อนหน้าสตริงย่อย พิจารณาองค์ประกอบ xml:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
สมมติว่าเราต้องการที่จะปรับเปลี่ยน 81 เพื่อให้มีค่าอื่น ๆ บางพูด 40. ครั้งแรกที่ระบุ.UID.21..UID.แล้วข้ามตัวละครทุกตัวรวมถึงจน\n .PercentCompleted.รูปแบบนิพจน์ทั่วไปและข้อมูลจำเพาะแทนที่คือ:
String hw = new String("<TASK>\n <UID>21</UID>\n <Name>Architectural design</Name>\n <PercentComplete>81</PercentComplete>\n</TASK>");
String pattern = new String ("(<UID>21</UID>)((.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
String replaceSpec = new String ("$1$2$440$6");
//note that the group (<PercentComplete>) is $4 and the group ((.|\n)*?) is $2.
String iw = hw.replaceFirst(pattern, replaceSpec);
System.out.println(iw);
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>40</PercentComplete>
</TASK>
กลุ่มย่อยน่าจะเป็นกลุ่มที่ขาดหายไป(.|\n) $3ถ้าเราทำให้มันไม่ใช่การจับภาพจาก(?:.|\n)นั้นคือ$3 (<PercentComplete>)ดังนั้นรูปแบบและreplaceSpecยังสามารถ:
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
และการเปลี่ยนทำงานอย่างถูกต้องเหมือนเดิม
โดยทั่วไปแล้วการค้นหาสามบรรทัดที่ต่อเนื่องกันใน Powershell จะมีลักษณะดังนี้:
$file = get-content file.txt -raw
$pattern = 'lineone\r\nlinetwo\r\nlinethree\r\n' # "windows" text
$pattern = 'lineone\nlinetwo\nlinethree\n' # "unix" text
$pattern = 'lineone\r?\nlinetwo\r?\nlinethree\r?\n' # both
$file -match $pattern
# output
True
น่าประหลาดใจนี่เป็นข้อความยูนิกซ์ที่พรอมต์ แต่ข้อความ windows ในไฟล์:
$pattern = 'lineone
linetwo
linethree
'
ต่อไปนี้เป็นวิธีพิมพ์ปลายบรรทัด:
'lineone
linetwo
linethree
' -replace "`r",'\r' -replace "`n",'\n'
# output
lineone\nlinetwo\nlinethree\n
วิธีหนึ่งคือใช้sแฟล็ก (เช่นเดียวกับคำตอบที่ยอมรับ):
/(.*)<FooBar>/s
วิธีที่สองคือใช้mแฟล็ก (multiline) และรูปแบบใด ๆ ต่อไปนี้:
/([\s\S]*)<FooBar>/m
หรือ
/([\d\D]*)<FooBar>/m
หรือ
/([\w\W]*)<FooBar>/m
jex.imเห็นภาพการแสดงออกปกติ: