Regex untuk menghapus nol di awal R, kecuali karakter akhir (atau hanya) nol

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" ""   ""

Ekspresi reguler di atas berasal dari utas SO ini yang menjelaskan cara menghapus semua nol di awal dari string dalam R. Sebagai konsekuensi dari ekspresi reguler ini, "000" dan "0" ditransformasikan menjadi "". Alih-alih, saya ingin menghapus semua nol di awal dari serangkaian karakter, kecuali untuk kasus-kasus ketika karakter akhir menjadi nol, atau satu-satunya karakter adalah nol.

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

Utas SO lainnya ini menjelaskan cara melakukan apa yang saya inginkan, tetapi saya rasa saya tidak mendapatkan sintaks yang benar, menerapkan solusi dalam R. Dan saya tidak terlalu memahami perbedaan antara solusi 1 dan 2 di bawah ini ( jika mereka memang bekerja).

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"

Apa regex yang tepat dalam R untuk mendapatkan apa yang saya inginkan?

Jason Hunter
sumber

Jawaban:

6

Anda dapat menghapus semua nol dari awal string tetapi bukan yang terakhir:

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

Lihat demo regex .

Detail

  • ^ - mulai dari sebuah string
  • 0+ - satu atau lebih nol
  • (?!$) - lookahead negatif yang gagal cocok jika ada akhir posisi string segera di sebelah kanan lokasi saat ini

Lihat demo R :

x <- c("005", "0AB", "000", "0")
sub("^0+(?!$)", "", x, perl=TRUE)
## => [1] "5"  "AB" "0"  "0"
Wiktor Stribiżew
sumber
1
regexcupu. Apa perbedaan kinerja (atau preferensi lain) antara pola Anda dan ini ^0*(.+)$atau itu ^0+(.+)$?
M--
2
@ M-- Ini adalah pola yang berbeda, disarankan untuk hanya membandingkan kinerja regexps yang setara. Milik Anda sedikit tidak efisien karena .dapat mencocokkan 0dan kedua pola yang berdampingan diukur secara tidak terbatas, tetapi hanya sedikit.
Wiktor Stribiżew
4

Kami dapat menambahkan satu kondisi lagi dengan pencarian regex untuk memeriksa nilai-nilai tidak nol setelah satu atau lebih nol ( 0+)

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

data

v1 <- c("005", "0AB", "000", "0")
akrun
sumber
1
Saya bukan regexguru dengan cara apa pun tetapi pencarian tidak efisien, bukan? Karena Anda memiliki dua subAnda mungkin ingin menghapus semua nol terkemuka dan ganti ""dengan 0? sub("^$", "0", sub("^0+", "", v1), perl = TRUE)
M--
2
@ M-- Ini tidak akan seefisien itu, tapi saya menggunakannya untuk mengikuti kode yang sama dengan OP
akrun
3

Anda bisa menggunakan pergantian untuk mencocokkan semua nol di string dalam grup penangkap atau mencocokkan semua nol dari awal string.

Dalam penggantian gunakan grup 1.

^0*(0)$|^0+

Demo Regex | R demo

Sebagai contoh

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

Keluaran

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

Atau bahkan lebih baik seperti yang dikomentari oleh Wiktor Stribiżew , Anda dapat menggunakan capture 0 tunggal dalam grup dan ulangi grup itu sendiri untuk menangkap instance terakhir dari nol.

^(0)+$|^0+

Demo Regex

Burung keempat
sumber
3
Saya akan menggunakan^(0)+$|^0+
Wiktor Stribiżew
3
Sepertinya sub("^0+(?!$)", "", x, perl=TRUE)juga akan berfungsi
Wiktor Stribiżew
2

regexOpsi lain :

^0*(.+)$

Inilah demo regex .

Menggunakan base::subdalam R:

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

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

Berikut ini adalah demo R .

Atau memperluas pada jawaban @ akrun :

sub("^$", "0", sub("^0+", "", c("005", "0AB", "000", "0")), perl = TRUE)
M--
sumber