Örneğin, bu normal ifade
(.*)<FooBar>
eşleşecek:
abcde<FooBar>
Ancak birden çok satıra eşleşmesini nasıl sağlayabilirim?
abcde
fghij<FooBar>
Örneğin, bu normal ifade
(.*)<FooBar>
eşleşecek:
abcde<FooBar>
Ancak birden çok satıra eşleşmesini nasıl sağlayabilirim?
abcde
fghij<FooBar>
Yanıtlar:
Dile bağlıdır, ancak normal ifadeye ekleyebileceğiniz bir değiştirici olmalıdır. PHP'de:
/(.*)<FooBar>/s
Sondaki s , noktanın yeni satırlar dahil tüm karakterlerle eşleşmesine neden olur .
s
değiştiriciyi desteklemiyor . Bunun yerine, [^]*
aynı etkiyi yapın.
m
değiştiriciyi kullanın
Bunu dene:
((.|\n)*)<FooBar>
Temelde sıfır veya daha fazla kez tekrarlanan "herhangi bir karakter veya yeni satır" yazıyor.
((.|\n|\r)*)<FooBar>
[\s\S]*
Veya tuşunu kullanın (?s).*
.
Soru şu, .
örüntü herhangi bir karakterle eşleşebilir mi? Cevap motordan motora değişir. Temel fark, desenin bir POSIX veya POSIX olmayan normal ifade kütüphanesi tarafından kullanılıp kullanılmadığıdır.
Hakkında özel not lua-desen: normal ifadeler olarak kabul edilmezler, ancak .
POSIX tabanlı motorlarla aynı şekilde herhangi bir karakterle eşleşirler.
Hakkında başka bir not matlab ve oktav: .
varsayılan olarak herhangi bir karakterle eşleşir ( demo ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
( tokens
bir abcde\n fghij
öğe içerir ).
Ayrıca, tümünde artırmak'nin normal ifadesi, varsayılan olarak nokta satır sonlarıyla eşleşir. Boost'un ECMAScript dilbilgisi, bunu regex_constants::no_mod_m
( kaynak ) ile kapatmanıza izin verir .
Gelince torpil(POSIX tabanlıdır) n
seçeneğini ( demo ) kullanın :select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
POSIX tabanlı motorlar :
Yalnızca .
satır sonlarıyla eşleşiyor, değiştirici kullanmaya gerek yok, bkz.darbe( demo ).
tcl( demo ),postgresql( demo ),r(TRE, taban R varsayılan motoru yok perl=TRUE
, taban R için perl=TRUE
veya stringr / stringi desenleri için (?s)
satır içi değiştiriciyi kullanın ) ( demo ) da .
aynı şekilde davranın .
Ancak , POSIX tabanlı araçların çoğu girişi satır satır işler. Bu nedenle, .
yalnızca kapsamda olmadıkları için satır sonlarıyla eşleşmez. Bunu nasıl geçersiz kılacağınıza dair bazı örnekler:
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'
( H;1h;$!d;x;
dosyayı belleğe kaydırır). Tüm satırların dahil edilmesi gerekiyorsa, sed '/start_pattern/,/end_pattern/d' file
(başlangıçtan kaldırma eşleşen satırlar dahil olarak sona erecektir) veya sed '/start_pattern/,/end_pattern/{{//!d;};}' file
(eşleşen satırlar hariç) düşünülebilir.perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
( -0
tüm dosyayı hafızaya alır, -p
verilen komut dosyasını uyguladıktan sonra dosyayı yazdırır -e
). Kullanmanın -000pe
dosyayı bozacağını ve Perl'in \n\n
kayıt ayırıcı olarak ardışık satırları ( ) kullandığını 'paragraf modunu' etkinleştireceğini unutmayın .grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
. Burada z
dosya kaydırmayı (?s)
etkinleştirir, .
desen için DOTALL modunu (?i)
etkinleştirir, büyük / küçük harf duyarsız modu etkinleştirir, \K
şimdiye kadar eşleşen metni atlar, *?
tembel bir niceleyicidir, (?=<Foobar>)
önceki konumla eşleşir <Foobar>
.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
( M
burada dosya kaydırmayı etkinleştirir). Not pcregrep
, Mac OS grep
kullanıcıları için iyi bir çözümdür .POSIX tabanlı olmayan motorlar :
s
değiştirici PCRE_DOTALL değiştirici : preg_match('~(.*)<Foobar>~s', $s, $m)
( demo )RegexOptions.Singleline
Bayrak ( demo ) kullanın : var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
(?s)
Satır içi seçeneğini kullan :$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
s
Değiştirici kullanın (veya (?s)
başlangıçtaki satır içi sürümü) ( demo ):/(.*)<FooBar>/s
re.DOTALL
(veya re.S
) bayrakları veya (?s)
satır içi değiştirici ( demo ) kullanın: m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(ve sonra if m:
, print(m.group(1))
)Pattern.DOTALL
Değiştirici (veya satır içi (?s)
bayrak) ( demo ) kullanın:Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
Model içi değiştirici kullanın ( demo ):regex = /(?s)(.*)<FooBar>/
(?s)
Değiştirici ( demo ) kullanın :"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
veya geçici çözümler [\d\D]
/ [\w\W]
/ [\s\S]
( demo ) kullanın:s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
) [\s\S]
Veya JS geçici çözümlerini kullanın ( demo ):regex rex(R"(([\s\S]*)<FooBar>)");
vba vbscript- JavaScript ile aynı yaklaşımı kullanın ([\s\S]*)<Foobar>
,. ( NOT : MultiLine
malı
RegExp
nesnesi bazen yanlışlıkla izin seçenek olduğu düşünülmektedir .
, aslında, sadece değiştirirken, satır sonları maç ^
ve $
başlasın maç davranışı / bitiş çizgileri yerine dizeleri aynı JS regex olduğu gibi ) davranış.)
yakut- /m
MULTILINE değiştiricisini ( demo ) kullanın :s[/(.*)<Foobar>/m, 1]
(?s)
: regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]
( demo )stringr
/ stringi
regex işlevleri, ayrıca (?s)
şunları kullanın : stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]
( demo )(?s)
Başlangıçta satır içi değiştiriciyi kullanın ( demo ):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
dotMatchesLineSeparators
veya (daha kolay) kullanın (?s)
:let rx = "(?s)(.*)<Foobar>"
(?s)
en kolay çalışır, ancak seçenek nasıl kullanılabilir :NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?s)
Değiştirici ( demo ) kullanın : "(?s)(.*)<Foobar>"
(Google E-Tablolarda, =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
)NOTLAR(?s)
:
POSIX olmayan çoğu motorda, (?s)
satır .
kesmelerini eşleştirmek için satır içi değiştirici (veya katıştırılmış bayrak seçeneği) kullanılabilir .
Desenin başına yerleştirilirse, desendeki (?s)
herkesin davranışını değiştirir .
. Eğer (?s)
başından sonra bir yere yerleştirilir, yalnızca .
onun sağındaki yer aldığını etkilenecektir sürece bu Python geçirilen bir kalıptır re
. Python'da re
, (?s)
konumdan bağımsız olarak , tüm desen .
etkilenir. (?s)
Etkisi kullanılarak durdurulur (?-s)
. Değiştirilmiş bir grup, yalnızca normal ifade düzeninin belirli bir aralığını etkilemek için kullanılabilir (örneğin Delim1(?s:.*?)\nDelim2.*
, ilk .*?
satırları yeni satırlar arasında ve ikinci satır .*
yalnızca satırın geri kalanıyla eşleşir).
POSIX notu :
POSIX olmayan normal ifade motorlarında, herhangi bir karakterle eşleşmek için [\s\S]
/ [\d\D]
/ [\w\W]
konstruktlar kullanılabilir.
POSIX'te, [\s\S]
regex kaçış dizileri köşeli ayraç ifadelerinde desteklenmediği için hiçbir karakterle (JavaScript veya POSIX olmayan herhangi bir motorda olduğu gibi) eşleşmiyor. [\s\S]
, tek bir karakterle eşleşen köşeli ayraç ifadeleri olarak ayrıştırılır \
veya s
veya S
.
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m
yansıtması için normal regex bayrakları için bir temel bayrak tanımı belirleyeceklerdir. Ve hakem her zaman satır içi değiştiricilerdir. Nerede (?-sm)(?s).*
sıfırlanır.
.
orada herhangi bir karakterle eşleşir (satır sonları dahil). Bu çevrimiçi Bash demosuna bakın .
Go
cevaba dahil etmek için ekstra oy !
Eclipse aramasını kullanıyorsanız, '.' Yapmak için "DOTALL" seçeneğini etkinleştirebilirsiniz. satır sınırlayıcılar dahil herhangi bir karakterle eşleşir: arama dizenizin başına "(? s)" eklemeniz yeterlidir. Misal:
(?s).*<FooBar>
(?s)
=>(?m)
Birçok normal ifade lehçelerinde, /[\S\s]*<Foobar>/
tam olarak istediğinizi yaparsınız. Kaynak
([\s\S]*)<FooBar>
Nokta, yeni satırlar (\ r \ n) dışındaki tüm öğelerle eşleşir. Bu yüzden TÜM karakterlerle eşleşecek \ s \ S kullanın.
[text rangeOfString:regEx options:NSRegularExpressionSearch]
. Teşekkürler!
<FooBar>
In Yakut yakut' m
' seçeneğini kullanabilirsiniz (çok satırlı):
/YOUR_REGEXP/m
Daha fazla bilgi için ruby-doc.org adresindeki Regexp belgelerine bakın .
biz de kullanabiliriz
(.*?\n)*?
açgözlü olmadan newline dahil her şeyi eşleştirmek
Bu, yeni satırı isteğe bağlı yapacaktır
(.*?|\n)*?
"."
normalde satır kesmeleriyle eşleşmez. Çoğu regex motoru, yeni satırlarla eşleşmesi için S
-flag ( DOTALL
ve olarak da adlandırılır SINGLELINE
) eklemenizi sağlar "."
. Bu başarısız olursa, böyle bir şey yapabilirsiniz [\S\s]
.
/(.*)<FooBar>/s
s, Nokta (.) öğesinin satır başı ile eşleşmesine neden olur
s
Bayraklar, PCRE'nin var (Perl ve PHP mevcuttur) en eksiksiz motoru. PCRE'de 10 bayrak (ve diğer birçok özellik) bulunurken, JavaScript'te yalnızca 3 bayrak ( gmi
) bulunur.
Java tabanlı düzenli ifadede şunları kullanabilirsiniz: [\s\S]
s
Java'da desene sadece bayrak ekleyebileceğiniz ve JavaScript'in s
bayrağı olmadığı için .
Desen değiştirici kullanın sU PHP'de istenen eşleşmeyi alacaktır.
preg_match('/(.*)/sU',$content,$match);
http://dreamluverz.com/developers-tools/regex-match-all-include-new-line http://php.net/manual/en/reference.pcre.pattern.modifiers.php
Diller içinde kullanım bağlamında, düzenli ifadeler satırlara değil, dizelere göre hareket eder. Bu nedenle, giriş dizesinin birden çok satırı olduğunu varsayarak normal ifadeyi normal şekilde kullanabilmeniz gerekir.
Bu durumda, "<FooBar>" mevcut olduğundan, verilen normal ifade tüm dizeyle eşleşecektir. Normal ifade uygulamasının özelliklerine bağlı olarak, 1 $ değeri ("(. *)" Den elde edilir) "fghij" veya "abcde \ nfghij" olur. Diğerlerinin söylediği gibi, bazı uygulamalar "." size yeni bir seçenek sunacak.
Satır tabanlı düzenli ifade kullanımı genellikle egrep gibi komut satırı şeyler içindir.
Aynı sorunu yaşadım ve muhtemelen en iyi şekilde çözemedim ama işe yarıyor. Gerçek maçımı yapmadan önce tüm satır sonlarını değiştirdim:
mystring= Regex.Replace(mystring, "\r\n", "")
HTML'yi manipüle ediyorum, bu nedenle satır sonları benim için gerçekten önemli değil.
Yukarıdaki tüm önerileri şanssız denedim, .Net 3.5 FYI kullanıyorum
(\s|\S)
benim için hile yapmak gibi görünüyor!
(?s)
için kullanın .
. (\s|\S)
Performansı yavaşlatacak şekilde kullanmayın .
Javascript'te satır sonları dahil olmak üzere sıfır ila sonsuz karakter aramak için [^] * kullanabilirsiniz.
$("#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>
genellikle. yeni satırlarla eşleşmediğinden, deneyin((.|\n)*)<foobar>
\r
:((?:.|\r?\n)*)<foobar>
Genellikle, bir alt dizeyi, alt dizeden önceki satırlara yayılmış birkaç anahtar kelimeyle değiştirmeliyiz. Bir xml öğesini düşünün:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
81 diyelim ki 40 diyelim başka bir değerle değiştirmek istediğimizi varsayalım. Önce tanımlayın .UID.21..UID.
, daha sonraya \n
kadar olan tüm karakterleri atlayın .PercentCompleted.
. Normal ifade deseni ve değiştirme belirtimi şunlardır:
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>
Alt grup (.|\n)
muhtemelen eksik gruptur $3
. Biz tarafından dışı yakalama yaparsanız (?:.|\n)
o zaman $3
olduğunu (<PercentComplete>)
. Böylece desen ve replaceSpec
ayrıca olabilir:
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
ve değiştirme daha önce olduğu gibi düzgün çalışır.
Tipik olarak Powershell'de ardışık üç satır aramak şöyle görünür:
$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
Tuhaf bir şekilde, bu komut isteminde unix metni olurdu, ancak bir dosyadaki Windows metni:
$pattern = 'lineone
linetwo
linethree
'
İşte satır sonlarını yazdırmanın bir yolu:
'lineone
linetwo
linethree
' -replace "`r",'\r' -replace "`n",'\n'
# output
lineone\nlinetwo\nlinethree\n
Bunun bir yolu s
bayrağı kullanmaktır (tıpkı kabul edilen cevap gibi):
/(.*)<FooBar>/s
İkinci yol, m
(çok satırlı) bayrağı ve aşağıdaki kalıplardan herhangi birini kullanmaktır:
/([\s\S]*)<FooBar>/m
veya
/([\d\D]*)<FooBar>/m
veya
/([\w\W]*)<FooBar>/m
jex.im düzenli ifadeleri görselleştirir: