Misalnya, regex ini
(.*)<FooBar>
akan cocok:
abcde<FooBar>
Tetapi bagaimana cara saya mencocokkannya dengan banyak baris?
abcde
fghij<FooBar>
Misalnya, regex ini
(.*)<FooBar>
akan cocok:
abcde<FooBar>
Tetapi bagaimana cara saya mencocokkannya dengan banyak baris?
abcde
fghij<FooBar>
Jawaban:
Itu tergantung pada bahasa, tetapi harus ada pengubah yang dapat Anda tambahkan ke pola regex. Dalam PHP itu adalah:
/(.*)<FooBar>/s
The s di akhir menyebabkan dot untuk mencocokkan semua karakter termasuk baris.
s
pengubah. Sebaliknya, lakukan [^]*
untuk efek yang sama.
m
modifikator
Coba ini:
((.|\n)*)<FooBar>
Pada dasarnya kata "karakter apa pun atau baris baru" berulang kali nol atau lebih.
((.|\n|\r)*)<FooBar>
[\s\S]*
atau (?s).*
.
Pertanyaannya adalah, bisakah .
pola cocok dengan karakter apa pun ? Jawabannya bervariasi dari mesin ke mesin. Perbedaan utama adalah apakah pola tersebut digunakan oleh perpustakaan regex POSIX atau non-POSIX.
Catatan khusus tentang lua-pola: mereka tidak dianggap sebagai ekspresi reguler, tetapi .
cocok dengan karakter apa pun di sana, sama dengan mesin berbasis POSIX.
Catatan lain tentang matlab dan oktaf: .
cocok dengan karakter apa pun secara default ( demo ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
( tokens
berisi abcde\n fghij
item).
Juga, di semua doronganTata bahasa regex titik tersebut cocok dengan jeda baris secara default. Tata bahasa naskah ECMAS Boost memungkinkan Anda untuk mematikannya dengan regex_constants::no_mod_m
( sumber ).
Untuk peramal(berbasis POSIX), gunakan n
opsi ( demo ):select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
Mesin berbasis POSIX :
Sekedar .
sudah cocok dengan jeda baris, tidak perlu menggunakan pengubah, lihatpesta( demo ).
Itu tcl( demo ),postgresql( demo ),r(TRE, basis mesin bawaan R tanpa perl=TRUE
, untuk basis R dengan perl=TRUE
atau stringr / Stringi pola, gunakan (?s)
inline pengubah) ( demo ) juga mengobati .
dengan cara yang sama.
Namun , sebagian besar alat berbasis POSIX memproses input baris demi baris. Oleh karena itu, .
tidak cocok dengan jeda baris hanya karena mereka tidak dalam ruang lingkup. Berikut ini beberapa contoh cara menimpa ini:
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'
( H;1h;$!d;x;
menyeruput file ke dalam memori). Jika seluruh garis harus disertakan, sed '/start_pattern/,/end_pattern/d' file
(menghapus dari awal akan berakhir dengan garis yang cocok disertakan) atau sed '/start_pattern/,/end_pattern/{{//!d;};}' file
(dengan garis yang cocok dikecualikan) dapat dipertimbangkan.perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
( -0
menyeruput seluruh file ke dalam memori, -p
mencetak file setelah menerapkan skrip yang diberikan oleh -e
). Perhatikan bahwa menggunakan -000pe
akan menghirup file dan mengaktifkan 'mode paragraf' di mana Perl menggunakan baris baru berurutan ( \n\n
) sebagai pemisah rekaman.grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
. Di sini, z
memungkinkan file (?s)
slurping , memungkinkan mode DOTALL untuk .
pola, (?i)
mengaktifkan mode case-insensitive, \K
menghilangkan teks yang cocok sejauh ini, *?
adalah quantifier malas, (?=<Foobar>)
cocok dengan lokasi sebelumnya <Foobar>
.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
( M
mengaktifkan file slurping di sini). Note pcregrep
adalah solusi yang baik untuk grep
pengguna Mac OS .Mesin non-POSIX :
s
pengubah pengubah PCRE_DOTALL : preg_match('~(.*)<Foobar>~s', $s, $m)
( demo )RegexOptions.Singleline
bendera ( demo ): var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
(?s)
opsi sebaris:$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
s
pengubah (atau (?s)
versi inline di awal) ( demo ):/(.*)<FooBar>/s
re.DOTALL
(atau re.S
) (?s)
pengubah flag atau inline ( demo ): m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(dan kemudian if m:
, print(m.group(1))
)Pattern.DOTALL
pengubah (atau inline (?s)
flag) ( demo ):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
pengubah dalam pola ( demo ):regex = /(?s)(.*)<FooBar>/
(?s)
pengubah ( demo ):"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
atau solusi [\d\D]
/ [\w\W]
/ [\s\S]
( demo ):s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
) Gunakan [\s\S]
atau solusi JS ( demo ):regex rex(R"(([\s\S]*)<FooBar>)");
vba vbscript- Gunakan pendekatan yang sama seperti dalam JavaScript ([\s\S]*)<Foobar>
,. ( CATATAN : MultiLine
Properti
RegExp
objek kadang-kadang keliru dianggap sebagai opsi untuk memungkinkan .
kecocokan lintas garis, sementara, pada kenyataannya, itu hanya mengubah ^
dan $
perilaku untuk mencocokkan awal / akhir garis daripada string , sama seperti di JS regex ) perilaku.)
rubi- Gunakan pengubah /m
MULTILINE ( demo ):s[/(.*)<Foobar>/m, 1]
(?s)
: regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]
( demo )stringr
/ stringi
fungsi regex yang ditenagai dengan mesin regex ICU, juga menggunakan (?s)
: stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]
( demo )(?s)
di awal ( demo ):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
dotMatchesLineSeparators
atau (lebih mudah) meneruskan (?s)
pengubah inline ke pola:let rx = "(?s)(.*)<Foobar>"
(?s)
bekerja paling mudah, tetapi di sini adalah bagaimana opsi dapat digunakan :NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?s)
pengubah ( demo ): "(?s)(.*)<Foobar>"
(di Google Spreadsheets, =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
)CATATAN ON(?s)
:
Pada sebagian besar mesin non-POSIX, (?s)
pengubah inline (atau opsi bendera tertanam) dapat digunakan untuk menegakkan .
agar sesuai dengan jeda baris.
Jika ditempatkan di awal pola, (?s)
ubah bahavior semua .
dalam pola. Jika (?s)
ditempatkan di suatu tempat setelah awal, hanya mereka yang .
akan terpengaruh yang terletak di sebelah kanan kecuali jika ini adalah pola yang diteruskan ke Python re
. Dalam Python re
, terlepas dari (?s)
lokasi, seluruh pola .
terpengaruh. The (?s)
Efek dihentikan menggunakan (?-s)
. Grup yang dimodifikasi hanya dapat digunakan untuk memengaruhi rentang pola regex tertentu (mis. Delim1(?s:.*?)\nDelim2.*
Akan membuat .*?
kecocokan pertama di seluruh baris baru dan yang kedua .*
hanya akan cocok dengan sisa baris lainnya).
Catatan POSIX :
Dalam mesin regex non-POSIX, untuk mencocokkan arang apa pun, [\s\S]
/ [\d\D]
/ [\w\W]
konstruksi dapat digunakan.
Dalam POSIX, [\s\S]
tidak cocok dengan karakter apa pun (seperti dalam JavaScript atau mesin non-POSIX) karena urutan pelarian regex tidak didukung di dalam ekspresi braket. [\s\S]
diuraikan sebagai ekspresi braket yang cocok dengan satu karakter, \
atau s
atau S
.
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m
untuk bendera regex mereka untuk mencerminkan hal itu. Dan wasit selalu pengubah inline. Di mana (?-sm)(?s).*
ulang.
.
cocok dengan semua karakter di sana (termasuk jeda baris). Lihat demo Bash online ini .
Go
dalam jawaban!
Jika Anda menggunakan pencarian Eclipse, Anda dapat mengaktifkan opsi "DOTALL" untuk membuat '.' cocok dengan karakter apa pun termasuk pembatas garis: cukup tambahkan "(? s)" di awal string pencarian Anda. Contoh:
(?s).*<FooBar>
(?s)
=>(?m)
Dalam banyak dialek regex, /[\S\s]*<Foobar>/
akan melakukan apa yang Anda inginkan. Sumber
([\s\S]*)<FooBar>
Titik cocok dengan semua kecuali baris baru (\ r \ n). Jadi gunakan \ s \ S, yang akan cocok dengan SEMUA karakter.
[text rangeOfString:regEx options:NSRegularExpressionSearch]
. Terima kasih!
<FooBar>
Di Ruby rubiAnda dapat menggunakan opsi ' m
' (multiline):
/YOUR_REGEXP/m
Lihat dokumentasi Regexp di ruby-doc.org untuk informasi lebih lanjut.
kita juga bisa menggunakan
(.*?\n)*?
untuk mencocokkan semuanya termasuk baris baru tanpa serakah
Ini akan membuat baris baru opsional
(.*?|\n)*?
"."
biasanya tidak cocok dengan jeda baris. Sebagian besar mesin regex memungkinkan Anda untuk menambahkan S
-flag (juga disebut DOTALL
dan SINGLELINE
) untuk membuat "."
juga cocok dengan baris baru. Jika itu gagal, Anda bisa melakukan sesuatu seperti [\S\s]
.
/(.*)<FooBar>/s
s menyebabkan Dot (.) cocok dengan carriage return
s
bendera ada di PCRE, paling mesin lengkap (tersedia dalam Perl dan PHP). PCRE memiliki 10 flag (dan banyak fitur lainnya) sementara JavaScript hanya memiliki 3 flag ( gmi
).
Dalam ekspresi reguler berbasis java yang dapat Anda gunakan [\s\S]
s
flag ke pola di Java dan JavaScript tidak memiliki s
flag.
Catatan yang (.|\n)*
bisa kurang efisien daripada (misalnya) [\s\S]*
(jika regex bahasa Anda mendukung pelarian semacam itu) dan daripada menemukan cara menentukan pengubah yang membuat. juga cocok dengan baris baru. Atau Anda dapat pergi dengan POSIX seperti alternatif [[:space:][:^space:]]*
.
Gunakan pengubah pola sU akan mendapatkan kecocokan yang diinginkan dalam 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
Dalam konteks penggunaan dalam bahasa, ekspresi reguler berlaku pada string, bukan garis. Jadi Anda harus dapat menggunakan regex secara normal, dengan asumsi bahwa string input memiliki beberapa baris.
Dalam hal ini, regex yang diberikan akan cocok dengan seluruh string, karena "<FooBar>" hadir. Bergantung pada spesifikasi implementasi regex, nilai $ 1 (diperoleh dari "(. *)") Akan berupa "fghij" atau "abcde \ nfghij". Seperti yang orang lain katakan, beberapa implementasi memungkinkan Anda untuk mengontrol apakah "." akan cocok dengan baris baru, memberi Anda pilihan.
Penggunaan ekspresi reguler berbasis garis biasanya untuk hal-hal baris perintah seperti egrep.
Saya memiliki masalah yang sama dan menyelesaikannya mungkin bukan cara terbaik tetapi berhasil. Saya mengganti semua jeda baris sebelum melakukan pertandingan yang sebenarnya:
mystring= Regex.Replace(mystring, "\r\n", "")
Saya memanipulasi HTML sehingga jeda baris tidak terlalu berarti bagi saya dalam hal ini.
Saya mencoba semua saran di atas tanpa hasil, saya menggunakan. Net 3.5 FYI
(\s|\S)
sepertinya melakukan trik untuk saya!
(?s)
untuk membuat .
cocok dengan karakter apa pun. Jangan gunakan (\s|\S)
itu akan memperlambat kinerja.
Di Javascript, Anda dapat menggunakan [^] * untuk mencari karakter nol hingga tak hingga, termasuk jeda baris.
$("#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>
umumnya. tidak cocok dengan baris baru, jadi cobalah((.|\n)*)<foobar>
\r
.:((?:.|\r?\n)*)<foobar>
Saya ingin mencocokkan blok if tertentu di java
...
...
if(isTrue){
doAction();
}
...
...
}
Jika saya menggunakan regExp
if \(isTrue(.|\n)*}
itu termasuk kurung kurawal untuk blok metode jadi saya gunakan
if \(!isTrue([^}.]|\n)*}
untuk mengecualikan kurung kurawal dari pertandingan wildcard.
Seringkali kita harus memodifikasi substring dengan beberapa kata kunci yang tersebar di seluruh baris sebelum substring. Pertimbangkan elemen xml:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
Misalkan kita ingin memodifikasi 81, ke beberapa nilai lain, katakan 40. Pertama identifikasi .UID.21..UID.
, lalu lewati semua karakter termasuk \n
sampai .PercentCompleted.
. Pola ekspresi reguler dan spesifikasi ganti adalah:
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>
Subkelompok (.|\n)
mungkin adalah grup yang hilang $3
. Jika kita membuatnya tidak menangkap pada (?:.|\n)
saat $3
itu (<PercentComplete>)
. Jadi polanya dan replaceSpec
bisa juga:
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
dan penggantian berfungsi dengan benar seperti sebelumnya.
Biasanya mencari tiga baris berturut-turut di Powershell akan terlihat seperti:
$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
Anehnya, ini akan menjadi teks unix saat diminta, tetapi jendela teks dalam file:
$pattern = 'lineone
linetwo
linethree
'
Berikut cara untuk mencetak akhir baris:
'lineone
linetwo
linethree
' -replace "`r",'\r' -replace "`n",'\n'
# output
lineone\nlinetwo\nlinethree\n
Salah satu caranya adalah dengan menggunakan s
flag (seperti jawaban yang diterima):
/(.*)<FooBar>/s
Cara kedua adalah dengan menggunakan m
flag (multiline) dan salah satu dari pola berikut:
/([\s\S]*)<FooBar>/m
atau
/([\d\D]*)<FooBar>/m
atau
/([\w\W]*)<FooBar>/m
jex.im memvisualisasikan ekspresi reguler: