Gelen Düzenli ifadeler Vikipedi'ye , bu gibi görünüyor [[:digit:]]
= [0-9]
= \d
.
Eşit olmadıkları koşullar nelerdir? Fark ne?
Bazı araştırmalardan sonra, bir farkın parantez ifadesinin [:expr:]
yerel ayara bağlı olduğunu düşünüyorum .
Gelen Düzenli ifadeler Vikipedi'ye , bu gibi görünüyor [[:digit:]]
= [0-9]
= \d
.
Eşit olmadıkları koşullar nelerdir? Fark ne?
Bazı araştırmalardan sonra, bir farkın parantez ifadesinin [:expr:]
yerel ayara bağlı olduğunu düşünüyorum .
Yanıtlar:
Evet, öyle [[:digit:]]
~ [0-9]
~ \d
(burada ~ vasıta aproximate).
Çoğu programlama dilinde (desteklendiği yerde) \d
≡ [[:digit:]]
(aynı). Daha az yaygındır (POSIX ama GNU içinde olduğunu ).\d
[[:digit:]]
grep -P
UNICODE'de birçok rakam var, örneğin:
123456789 # Hindu-Arabic
Arap rakamları
٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI
Bunların tümü veya içerisinde bulunabilir .[[:digit:]]
\d
Bunun yerine, [0-9]
genellikle yalnızca ASCII basamaktır 0123456789
.
Pek çok dil var: Perl, Java, Python, C İçinde genişletilmiş bir anlam ifade eden [[:digit:]]
(ve \d
). Örneğin, bu perl kodu yukarıdan gelen tüm rakamlarla eşleşecektir:
$ a='0123456789 ٠١٢٣٤٥٦٧٨٩ ۰۱۲۳۴۵۶۷۸۹ ߀߁߂߃߄߅߆߇߈߉ ०१२३४५६७८९'
$ echo "$a" | perl -C -pe 's/[^\d]//g;' ; echo
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९
Unicode özelliklerine sahip tüm karakterleri seçmek için eşdeğerdir Numeric
ve digits
:
$ echo "$a" | perl -C -pe 's/[^\p{Nd}]//g;' ; echo
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९
Hangi grep yeniden üretilebilir (pcre'nin özel sürümü Perl'den farklı bir sayısal kod noktaları listesi içerebilir):
$ echo "$a" | grep -oP '\p{Nd}+'
0123456789
٠١٢٣٤٥٦٧٨٩
۰۱۲۳۴۵۶۷۸۹
߀߁߂߃߄߅߆߇߈߉
०१२३४५६७८९
Görmek için [0-9] olarak değiştirin:
$ echo "$a" | grep -o '[0-9]\+'
0123456789
Spesifik POSIX BRE veya ERE için: (POSIX ama GNU'da olan desteklenmez ).
POSIX tarafından sayısal karakter sınıfına karşılık gelmesi gerekir; bu da ISO C tarafından 0 - 9 arasındaki karakterlerden başka bir şey değildir. Yani sadece C yerele tüm , , ve tam olarak aynı anlama. Hiçbir olası yanlış yorumlamaları vardır fazla yardımcı programlar mevcuttur ve sadece anlama yaygındır . Birkaç kamu tarafından desteklenmektedir.\d
grep -P
[[:digit:]]
[0-9]
[0123456789]
\d
[[:digit:]]
[0123456789]
[[:digit:]]
[0123456789]
\d
İçin olduğu gibi [0-9]
, sadece C yereli POSIX'e ile tanımlanır aralık ifadelerinin anlamı; diğer yerlerde farklı olabilir (kod noktası sırası veya harmanlama sırası veya başka bir şey olabilir).
Bazı uygulamalar bir seriyi ASCII düzenden farklı bir şey olarak anlayabilir (örneğin, ksh93):
$ LC_ALL=en_US.utf8 ksh -c 'a="'"$a"'";echo "${a//[0-9]}"'
۹ ߀߁߂߃߄߅߆߇߈߉ ९
Ve bu, gerçekleşmeyi bekleyen bir böcek kaynağı.
iswctype()
ve POSIX yardımcı programlarındaki BRE / ERE / joker karakterler, [0-9] ve [[: digit:]] yalnızca 0123456789 ile eşleşir. Ve bu, standardın bir sonraki revizyonunda açıklanacak
perl
's \d
diğer komut ondalık basamak eşleşen Unicode modunda. Bunun için teşekkürler. PCRE ile, GNU'daki (*UCP)
gibi grep -Po '(*UCP)\d'
veya grep -Po '(*UCP)[[:digit:]]
Unicode özelliklerine dayalı sınıflar için görün.
[:digit:]
Sözdiziminin, yerelleştirmeyi kullanmak istediğinizi, kullanıcı rakam olarak gördüğü şeyin bu olduğunu kabul edeceğini kabul ediyorum . Hiç kullanmıyorum, [:digit:]
çünkü pratikte [0-9]
her durumda olduğu gibi ve aynı , her zaman 0123456789'da eşleştirmek istiyorum, hiçbir zaman eşleşmek ٠١٢٣٤٥٦٧٨٩
istemiyorum ve birinin ondalık basamakta eşleşmek isteyeceği bir kullanım durumu düşünemiyorum POSIX yardımcı programlarıyla herhangi bir komut dosyasında. Ayrıca, zsh ML hakkındaki güncel tartışmaya[:blank:]
bakın . Bu karakter sınıfları biraz dağınık.
Bu rakamı nasıl tanımladığınıza bağlıdır; [0-9]
sadece ASCII olanlar olma eğilimindedir (veya ASCII'nin veya ASCII'nin bir üstkümesi olmayan ancak ASCII'deki aynı 10 hane yalnızca farklı bit gösterimleri (EBCDIC) olan başka bir şey olma eğilimindedir; \d
Öte yandan, sadece basit rakamlar (Perl'in eski versiyonları veya /a
normal ifade bayrağının etkin olduğu Perl’in modern versiyonları ) olabilir veya Unicode eşleşmesi, \p{Digit}
daha büyük rakamlardan oluşan [0-9]
veya onlardan daha büyük olan bir Unicode eşleşmesi olabilir /\d/a
.
$ perl -E 'say "match" if 42 =~ m/\d/'
match
$ perl -E 'say "match" if "\N{U+09EA}" =~ m/\d/'
match
$ perl -E 'say "match" if "\N{U+09EA}" =~ m/\d/a'
$ perl -E 'say "match" if "\N{U+09EA}" =~ m/[0-9]/'
$
perldoc perlrecharclass
Daha fazla bilgi için veya nasıl davrandığını görmek için söz konusu dilin belgelerine bakın.
Ama bekleyin, dahası var! Yerel ayar, hangi \d
eşleşmeleri de değiştirebilir ; bu nedenle \d
, Unicode kümesinin tamamından daha az rakamla eşleşebilir ve (umarım genellikle de) [0-9]
. Bu, isdigit(3)
( [0-9]
) ve isnumber(3)
( [0-9
artı yerel ayarlardan başka ne olursa olsun ) arasındaki C farkına benzer .
Rakamın değerini almak için yapılabilecek aramalar olabilir, olmasa bile [0-9]
:
$ perl -MUnicode::UCD=num -E 'say num(4)'
4
$ perl -MUnicode::UCD=num -E 'say num("\N{U+09EA}")'
4
$
isnumber()
bir BSD şey olduğunu düşünüyorum , en azından göründüğü adam sayfasına göre
[0-9]
.
Farklı bir anlam [0-9]
, [[:digit:]]
ve \d
diğer yanıtlar sunulmaktadır. Burada regex motorunun uygulanmasında farklılıklar eklemek istiyorum.
[[:digit:]] \d
grep -E ✓ ×
grep -P ✓ ✓
sed ✓ ×
sed -E ✓ ×
Yani [[:digit:]]
her zaman çalışır , \d
bağlıdır. Grep'in el kitabında [[:digit:]]
sadece yerel ayarlarda 0-9
olduğu C
söylenir.
PS1: Daha fazlasını biliyorsanız, lütfen tabloyu genişletin.
PS2: GNU grep 3.1 ve GNU 4.4 test için kullanılır.
grep
ve sed
muhtemelen diğerleri vs GNU sürümleri arasındaki en büyük fark,. O hangi sürümünü bahsetti Bu cevap daha yararlı olabilir grep
ve sed
bunun ifade eder. Veya bu tablonun kaynağının ne olduğuna bağlı olarak. 2) bu tablo metne dönüştürülebilir, çünkü resim olmasını gerektiren hiçbir şey içermez
re
[[: digit:]] desteklemediğini, ancak kütüphanedeki eklentinin regex
onu desteklediğini unutmayın, böylece her zaman işe yarayan biraz kıkırdatacağım. Her zaman posix şikayet durumlarında çalışır.
Teorik farklar, diğer cevaplarda zaten oldukça iyi açıklanmıştır, bu nedenle pratik farkları açıklamak için kalır .
Bir basamağı eşleştirmek için kullanılan yaygın kullanım durumlarından bazıları:
Genelde, bazı numaraları sıkıştırmak istediğinizde, numaraların kendileri garip bir biçimde biçimlendirilmiş bir metin dosyasındadır. Bunları programınızda kullanmak üzere çıkarmak istiyorsunuz. Muhtemelen sayı biçimini (dosyaya bakarak) ve şu anki yerel ayarlarınızı söyleyebilirsiniz, bu nedenle , işi aldığı sürece herhangi bir form kullanmanız uygundur . \d
en az tuşa basılmasını gerektirir, bu yüzden çok sık kullanılır.
Bazı güvenilir olmayan kullanıcı girişleriniz var (belki bir web formundan) ve herhangi bir sürpriz içermediğinden emin olmalısınız. Belki bir veritabanında sayısal bir alanda saklamak veya bir sunucuda çalıştırmak için kabuk komutuna parametre olarak kullanmak istiyorsunuz. Bu durumda, gerçekten istiyorsun [0-9]
, çünkü en kısıtlayıcı ve tahmin edilebilir olanı.
Tehlikeli bir şey için kullanmayacağınız bir miktar veriye sahipsiniz, ancak sayı olup olmadığını bilmek güzel olurdu. Örneğin, programınız kullanıcının bir adres girmesine izin verir ve giriş bir ev numarası içermiyorsa olası bir yazım hatasını vurgulamak istersiniz. Bu durumda, muhtemelen mümkün olduğu kadar geniş [[:digit:]]
olmak istersiniz, bu şekilde gitmenin yolu da öyle .
Bunlar rakam eşleştirme için en yaygın üç kullanım durumu olarak görünmektedir. Önemli bir şeyi kaçırdığımı düşünüyorsanız, lütfen bir yorum bırakın.