ตัวอย่างเช่น 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"
( -0
slurps ไฟล์ทั้งหมดในหน่วยความจำ-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>/s
re.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
/ stringi
regex ที่ขับเคลื่อนด้วยเอนจิน 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]
จะแยกเป็นนิพจน์วงเล็บที่ตรงกับถ่านเดียว\
หรือหรือs
S
#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เห็นภาพการแสดงออกปกติ: