Bazen boşlukla eşleşmek istiyorum ancak satırsonu ile eşleşmemek istiyorum.
Şimdiye kadar başvuruyordum [ \t]
. Daha az garip bir yol var mı?
Bazen boşlukla eşleşmek istiyorum ancak satırsonu ile eşleşmemek istiyorum.
Şimdiye kadar başvuruyordum [ \t]
. Daha az garip bir yol var mı?
Yanıtlar:
Perl sürüm 5.10 ve üzeri, yan dikey ve yatay karakter sınıflarını \v
ve \h
genel boşluk karakter sınıfını destekler\s
En temiz çözüm yatay boşluk karakter sınıfını kullanmaktır \h
. Bu, ASCII kümesinden sekme ve boşluk, genişletilmiş ASCII'den kopmayan boşluk veya bu Unicode karakterlerden herhangi biriyle eşleşir
U+0009 CHARACTER TABULATION
U+0020 SPACE
U+00A0 NO-BREAK SPACE (not matched by \s)
U+1680 OGHAM SPACE MARK
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2007 FIGURE SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+202F NARROW NO-BREAK SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE
Dikey boşluk desen \v
az yararlı olduğunu, ancak bu karakterleri eşleşir
U+000A LINE FEED
U+000B LINE TABULATION
U+000C FORM FEED
U+000D CARRIAGE RETURN
U+0085 NEXT LINE (not matched by \s)
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
Eşleşen yedi dikey boşluk karakteri ve eşleşen \v
on sekiz yatay karakter vardır \h
. \s
yirmi üç karakterle eşleşir
Tüm boşluk karakterleri üst üste binmeden dikey veya yataydır , ancak uygun alt kümeler değildir, çünkü \h
U + 00A0 NO-BREAK SPACE ile \v
eşleşir ve ayrıca ikisi tarafından eşleşmeyen U + 0085 NEXT LINE ile eşleşir\s
\h
yalnızca destekleyen dillerde çalışır PCRE
.
[[:blank:]]
-
veya"\xA0"
\h
Notepad ++ 1 veya daha fazla bitişik olmayan yeni satır boşlukları üzerinde bir bul / değiştir yapan benim kullanım durumum için mükemmel çalıştı bahsetmek istiyorum . Başka hiçbir şey işe yaramadı.
\h
biraz standart dışı yapan şey, dahil edilmesidir MONGOLIAN VOWEL SEPARATOR
. Unicode boşluk olarak değerlendirmez. Bu nedenle Perl \h
, POSIX blank
( [[:blank:]]
Perl'de, \p{Blank}
Java'da) ve Java 8'den farklıdır \h
. Kuşkusuz, bu bir uç durum.
Çift negatif kullanın:
/[^\S\r\n]/
Yani, boşluk değil (başkent S tamamlar) veya satırbaşı veya satırsonu değil. Değil dış Dağıtma ( yani , tamamlayıcı ^
birlikte karakter sınıfında) De Morgan yasa , bu eşdeğerdir “boşluk değil satırbaşı veya satır.” Hem dahil \r
ve \n
klasik Mac OS (CR) ve DOS imsi (CR LF), desende doğru Unix (LF) tüm kolları yeni satır konvansiyonlar .
Benim sözüme gerek yok:
#! /usr/bin/env perl
use strict;
use warnings;
use 5.005; # for qr//
my $ws_not_crlf = qr/[^\S\r\n]/;
for (' ', '\f', '\t', '\r', '\n') {
my $qq = qq["$_"];
printf "%-4s => %s\n", $qq,
(eval $qq) =~ $ws_not_crlf ? "match" : "no match";
}
Çıktı:
"" => eşleşme "\ f" => eşleme "\ t" => eşleme "\ r" => eşleşme yok "\ n" => eşleşme yok
Dikey sekmenin hariç tutulduğuna dikkat edin , ancak bu v5.18'de ele alınmaktadır .
Çok sert itiraz etmeden önce, Perl belgeleri aynı tekniği kullanır. Bir dipnot perlrecharclass ait “Boşluk” bölümünde okur
Perl v5.18'den önce
\s
dikey sekmeyle eşleşmiyordu.[^\S\cK]
(belirsiz)\s
geleneksel olarak yapılanlarla eşleşir .
Perlrecharclass aynı bölümde ayrıca çift negatifler için dil öğretmenlerinin muhalefet rahatsız olmaz diğer yaklaşım önerir.
Zaman dışında yerel ve Unicode kuralları veya /a
anahtar etkisi olduğu “ \s
kibrit [\t\n\f\r ]
ve, Perl v5.18, dikey sekmede başlayan \cK
.” Boşlukları eşleştirin, yeni satır için değil, atın \r
ve \n
bırakın /[\t\f\cK ]/
.
Metniniz Unicode ise , yukarıda belirtilen belgeler bölümündeki tablodan bir desen oluşturmak için aşağıdaki alt bölüme benzer kodu kullanın .
sub ws_not_nl {
local($_) = <<'EOTable';
0x0009 CHARACTER TABULATION h s
0x000a LINE FEED (LF) vs
0x000b LINE TABULATION vs [1]
0x000c FORM FEED (FF) vs
0x000d CARRIAGE RETURN (CR) vs
0x0020 SPACE h s
0x0085 NEXT LINE (NEL) vs [2]
0x00a0 NO-BREAK SPACE h s [2]
0x1680 OGHAM SPACE MARK h s
0x2000 EN QUAD h s
0x2001 EM QUAD h s
0x2002 EN SPACE h s
0x2003 EM SPACE h s
0x2004 THREE-PER-EM SPACE h s
0x2005 FOUR-PER-EM SPACE h s
0x2006 SIX-PER-EM SPACE h s
0x2007 FIGURE SPACE h s
0x2008 PUNCTUATION SPACE h s
0x2009 THIN SPACE h s
0x200a HAIR SPACE h s
0x2028 LINE SEPARATOR vs
0x2029 PARAGRAPH SEPARATOR vs
0x202f NARROW NO-BREAK SPACE h s
0x205f MEDIUM MATHEMATICAL SPACE h s
0x3000 IDEOGRAPHIC SPACE h s
EOTable
my $class;
while (/^0x([0-9a-f]{4})\s+([A-Z\s]+)/mg) {
my($hex,$name) = ($1,$2);
next if $name =~ /\b(?:CR|NL|NEL|SEPARATOR)\b/;
$class .= "\\N{U+$hex}";
}
qr/[$class]/u;
}
Çift negatif hile, alfabetik karakterleri eşleştirmek için de kullanışlıdır. Bunun \w
"kelime karakterleri", alfabetik karakterler , rakam ve alt çizgi ile eşleştiğini unutmayın . Biz çirkin Amerikalılar bazen bunu şöyle derler,
if (/[A-Za-z]+/) { ... }
ancak çift negatif karakter sınıfı yerel ayara saygı duyabilir:
if (/[^\W\d_]+/) { ... }
“Bir kelime karakterini ancak rakam ya da alt çizgiyi değil” bu şekilde ifade etmek biraz opaktır. POSIX karakter sınıfı amacı daha doğrudan iletir
if (/[[:alpha:]]+/) { ... }
veya szbalint'in önerdiği gibi bir Unicode özelliği ile
if (/\p{Letter}+/) { ... }
\r
böylece de maçın gelenler exluding düşünün, Windows üzerinde örneğin: /[^\S\r\n]/
)
\h
Mevcut olduğunda bu çözümü kullanmak için hiçbir mazeret yoktur .
Greg'in cevabında satır başı da içeren bir varyasyon :
/[^\S\r\n]/
Bu normal ifade, /[^\S\n]/
hayır ile olduğundan daha güvenlidir \r
. Benim gerekçem, Windows'un \r\n
yeni satırlar için ve Mac OS 9'un kullanılmasıdır \r
. Sen bulmak olası \r
olmadan \n
günümüzde, ama bunu bulursak, o ortalama bir şey ama bir yeni satır yapamadı. Dolayısıyla, \r
yeni bir satır anlamına gelebileceğinden, bunu da hariç tutmalıyız.
Aşağıdaki normal ifade, beyaz boşluklarla eşleşir, ancak yeni bir satır karakteriyle eşleşmez.
(?:(?!\n)\s)
Şaryo iadesi eklemek istiyorsanız \r
, |
operatöre negatif ileriye baktığınızda ekleyin .
(?:(?![\n\r])\s)
+
Yakalamayan grubun ardından bir veya daha fazla boşlukla eşleşecek şekilde ekleyin .
(?:(?![\n\r])\s)+
Neden insanların [[:blank:]]
herhangi bir yatay boşluklar ( boşluklar ve sekmeler ) eşleşen POSIX karakter sınıfı söz başarısız oldu bilmiyorum . Bu POSIX karakter sınıfı, BRE ( Temel Normal İfadeler ), ERE ( Genişletilmiş Düzenli İfade ), PCRE ( Perl Uyumlu Normal İfade ) üzerinde çalışır.
Aradığın şey POSIX blank
karakter sınıfı. Perl'de şöyle denir:
[[:blank:]]
Java'da (etkinleştirmeyi unutmayın UNICODE_CHARACTER_CLASS
):
\p{Blank}
Benzeriyle karşılaştırıldığında \h
, POSIX blank
birkaç regex motoru tarafından desteklenmektedir ( referans ). Bunun en büyük yararı, tanımının Ek C: Unicode Düzenli İfadelerin Uyumluluk Özellikleri ve Unicode'u destekleyen tüm regex lezzetlerinde standart olarak sabitlenmiş olmasıdır. (Örneğin, Perl'de \h
ek olarak eklemeyi seçer MONGOLIAN VOWEL SEPARATOR
.) Bununla birlikte, lehine bir argüman \h
her zaman Unicode karakterleri algılamasıdır (motorlar hangisi üzerinde anlaşmasa bile), POSIX karakter sınıfları genellikle varsayılan ASCII'dir -sadece (Java'da olduğu gibi).
Ancak sorun, Unicode'a bağlı kalmanın bile sorunu% 100 çözmemesi. Unicode'da boşluk olarak kabul edilmeyen aşağıdaki karakterleri göz önünde bulundurun:
U + 180E Moğolca Sesli Ayırıcı
U + 200B SIFIR GENİŞLİK ALANI
U + 200C SIFIR GENİŞLİK BİRLEŞTİRMEYEN
U + 200D SIFIR GENİŞLİK BİRLEŞTİRİCİ
U + 2060 WORD JOINER
U + FEFF SIFIR GENİŞLİK KIRILMAYAN ALAN
Alındığı https://en.wikipedia.org/wiki/White-space_character
Yukarıda adı geçen Moğolca sesli harf ayırıcısı, muhtemelen iyi bir nedenden dolayı dahil değildir. 200C ve 200D ile birlikte kelimeler (AFAIK) içinde meydana gelir ve bu nedenle diğer tüm boşlukların uyduğu kardinal kuralı ihlal eder: onunla token yapabilirsiniz. Daha çok değiştiriciler gibidirler. Ancak ZERO WIDTH SPACE
, WORD JOINER
ve ZERO WIDTH NON-BREAKING SPACE
(bir bayt sırası işareti dışındaki olarak kullanılırsa) kitabımda boşluk kuralı uygun. Bu yüzden onları yatay boşluk karakter sınıfıma dahil ediyorum.
Java dilinde:
static public final String HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]"
perl
orijinal sorudaki etikettir.
[\p{Blank}\u200b\u180e]
gerekli olduğunu bilmek beni rahatsız ediyor . Kuşkusuz, bir sesli harf ayırıcısının bir boşluk karakteri olarak kabul edilmemesi mantıklıdır , ancak neden sıfır genişlikli alan \s
ve ve gibi sınıflarda olmamalıdır \p{Blank}
.
m/ /g
sadece boşluk / /
bırakın ve işe yarayacaktır. Veya kullan \S
- sekme, yeni satırlar, boşluklar ve benzeri tüm özel karakterlerin yerini alacaktır.
[\r\f]
.