Son (veya yalnızca) karakter sıfır değilse, R'deki önde gelen sıfırları kaldırmak için normal ifade


9
gsub("(?<![0-9])0+", "", c("005", "0AB", "000", "0"), perl = TRUE)
#> [1] "5"  "AB" ""   ""
gsub("(^|[^0-9])0+", "\\1", c("005", "0AB", "000", "0"), perl = TRUE)
#> [1] "5"  "AB" ""   ""

Yukarıdaki normal ifade , R'deki bir dizeden tüm önde gelen sıfırların nasıl kaldırılacağını açıklayan bu SO iş parçacığından gelir . Bu normal ifade sonucunda hem "000" hem de "0", "" biçimine dönüştürülür. Bunun yerine, son karakterin sıfır olduğu veya tek karakterin sıfır olduğu durumlar dışında, bir karakter dizesindeki tüm önde gelen sıfırları kaldırmak istiyorum.

"005" would become "5"
"0AB" would become "AB"
"000" would become "0"
"0"   would become "0"

Bu diğer SO iş parçacığı istediğimi nasıl yapacağımı açıklıyor, ancak sözdizimini oldukça doğru bir şekilde aldığımı, R'deki çözümü uyguladığımı sanmıyorum Ve aşağıdaki 1. ve 2. çözüm arasındaki farkı gerçekten anlamıyorum ( eğer gerçekten çalıştılarsa).

gsub("s/^0*(\d+)$/$1/;", "", c("005", "0AB", "000", "0"), perl = TRUE)  # 1st solution
# Error: '\d' is an unrecognized escape in character string starting ""s/^0*(\d"
gsub("s/0*(\d+)/$1/;", "", c("005", "0AB", "000", "0"), perl = TRUE)    # 2nd solution
# Error: '\d' is an unrecognized escape in character string starting ""s/0*(\d"

İstediğimi elde etmek için R'de uygun regex nedir?

Yanıtlar:


6

Bir dizenin başındaki tüm sıfırları kaldırabilirsiniz, ancak sonuncuyu değil:

sub("^0+(?!$)", "", x, perl=TRUE)

Normal ifade tanıtımına bakın .

ayrıntılar

  • ^ - bir dizenin başlangıcı
  • 0+ - bir veya daha fazla sıfır
  • (?!$) - geçerli konumun hemen sağında dize konumunun sonu varsa eşleşmeyi başaramayan negatif bir ileri okuma

R demosuna bakın :

x <- c("005", "0AB", "000", "0")
sub("^0+(?!$)", "", x, perl=TRUE)
## => [1] "5"  "AB" "0"  "0"

1
regexçaylak. Modelinizle bu model arasındaki performans farkı (veya diğer tercihler) nedir ^0*(.+)$veya ^0+(.+)$?
M--

2
@ M-- Bunlar farklı kalıplardır, sadece eşdeğer normal ifadelerin performansını karşılaştırmanız önerilir. Sizinki .eşleşebileceği kadar verimsiz 0ve her iki bitişik desen de süresiz olarak ölçülüyor, ama sadece küçük bir parça.
Wiktor Stribiżew

4

Bir veya daha fazla sıfırdan sonra sıfır olmayan değerlerin olup olmadığını kontrol etmek için normal ifadeli bir görünüme sahip bir koşul daha ekleyebiliriz ( 0+)

sub("(?<![0-9])0+(?=[^0])", "", sub("^0+$", "0", v1), perl = TRUE)
#[1] "5"  "AB" "0"  "0" 

veri

v1 <- c("005", "0AB", "000", "0")

1
Ben regexhiçbir şekilde guru değilim ama bakış açıları etkili değil, değil mi? Eğer iki tane beri subtüm baştaki sıfırları kaldırmak ve değiştirmek isteyebilir ""ile 0? sub("^$", "0", sub("^0+", "", v1), perl = TRUE)
M--

2
@ M-- Bu kadar verimli olmaz, ama OP ile aynı kodu takip etmek için kullandım
akrun


3

Bir yakalama grubundaki dizedeki tüm sıfırları eşleştirmek veya dizenin başlangıcından itibaren tüm sıfırları eşleştirmek için bir alternatif kullanabilirsiniz.

Değiştirme grubunda 1 kullanın.

^0*(0)$|^0+

Regex demosu | R demosu

Örneğin

sub("^0*(0)$|^0+", "\\1", c("005", "0AB", "000", "0"))

Çıktı

[1] "5"  "AB" "0"  "0"

Veya Wiktor Stribiżew tarafından yorumlandığı gibi daha da iyisi , bir grupta tek bir 0 yakalamayı kullanabilir ve sıfırın son örneğini yakalamak için grubun kendisini tekrarlayabilirsiniz.

^(0)+$|^0+

Normal ifade


3
Kullanacağım^(0)+$|^0+
Wiktor Stribiżew

3
Görünüşe göre sub("^0+(?!$)", "", x, perl=TRUE)işe yarayacak
Wiktor Stribiżew

2

Başka bir regexseçenek:

^0*(.+)$

İşte bir regex demosu .

base::subR'de kullanma :

sub("^0*(.+)$", "\\1", c("005", "0AB", "000", "0"))  

 ## [1] "5"  "AB" "0"  "0" 

İşte bir R demosu .

Veya @ akrun'un cevabını genişletmek :

sub("^$", "0", sub("^0+", "", c("005", "0AB", "000", "0")), perl = TRUE)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.