Regex เพื่อลบศูนย์นำหน้าใน R ยกเว้นว่าอักขระตัวสุดท้าย (หรือเท่านั้น) เป็นศูนย์


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

นิพจน์ทั่วไปด้านบนมาจากเธรด SO นี้ซึ่งอธิบายวิธีลบศูนย์นำหน้าทั้งหมดออกจากสตริงใน R เนื่องจากการแสดงออกปกตินี้ทั้ง "000" และ "0" จะถูกเปลี่ยนเป็น "" แต่ฉันต้องการลบศูนย์นำหน้าทั้งหมดออกจากสตริงอักขระยกเว้นกรณีที่อักขระสุดท้ายปรากฏเป็นศูนย์หรืออักขระเพียงตัวเดียวคือศูนย์

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

เธรด SO อื่น ๆ นี้อธิบายวิธีการทำสิ่งที่ฉันต้องการ แต่ฉันไม่คิดว่าฉันได้รับไวยากรณ์ค่อนข้างถูกต้องใช้วิธีแก้ปัญหาในอาร์และฉันไม่เข้าใจความแตกต่างระหว่างโซลูชันที่ 1 และ 2 ด้านล่าง ( ถ้าพวกเขาทำงานจริง ๆ )

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"

regex ที่เหมาะสมใน R คืออะไรเพื่อให้ได้ในสิ่งที่ฉันต้องการ

คำตอบ:


6

คุณสามารถลบค่าศูนย์ทั้งหมดจากจุดเริ่มต้นของสตริง แต่ไม่ใช่ค่าสุดท้าย:

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

ดูการสาธิต regex

รายละเอียด

  • ^ - เริ่มต้นของสตริง
  • 0+ - ศูนย์หนึ่งศูนย์ขึ้นไป
  • (?!$) - lookahead เชิงลบที่ไม่ตรงกับการแข่งขันหากมีจุดสิ้นสุดของตำแหน่งสตริงทางด้านขวาของตำแหน่งปัจจุบัน

ดูตัวอย่าง R :

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

1
regexอ่อนหัด. สิ่งที่แตกต่างประสิทธิภาพ (หรือการตั้งค่าอื่น ๆ ) ระหว่างรูปแบบและหนึ่งนี้ของคุณ^0*(.+)$หรือ^0+(.+)$?
M--

2
@ M-- รูปแบบเหล่านี้แตกต่างกันขอแนะนำให้เปรียบเทียบประสิทธิภาพของ regexps ที่เทียบเท่าเท่านั้น ของคุณมีประสิทธิภาพเล็กน้อยที่.สามารถจับคู่ได้0และทั้งสองรูปแบบที่อยู่ติดกันนั้นมีปริมาณไม่ จำกัด แต่เพียงเล็กน้อย
Wiktor Stribiżew

4

เราสามารถเพิ่มเงื่อนไขอีกหนึ่งเงื่อนไขโดยใช้การค้นหาแบบ regex เพื่อตรวจสอบค่าที่ไม่เป็นศูนย์ใด ๆ หลังจากหนึ่งศูนย์ขึ้นไป ( 0+)

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

ข้อมูล

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

1
ฉันไม่ได้เป็นregexกูรู แต่อย่างใด lookarounds ไม่มีประสิทธิภาพใช่ไหม? เนื่องจากคุณมีสองsubคุณอาจต้องการลบศูนย์นำหน้าและแทนที่""ด้วย0? sub("^$", "0", sub("^0+", "", v1), perl = TRUE)

2
@ M-- มันจะไม่ได้ผล แต่ฉันใช้มันเพื่อทำตามรหัสเดียวกันกับ OP
akrun


3

คุณสามารถใช้ทางเลือกเพื่อจับคู่ศูนย์ทั้งหมดในสตริงในกลุ่มการจับภาพหรือจับคู่ศูนย์ทั้งหมดตั้งแต่เริ่มต้นของสตริง

ในกลุ่มใช้ทดแทน 1

^0*(0)$|^0+

สาธิต Regex | การสาธิต R

ตัวอย่างเช่น

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

เอาท์พุต

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

หรือดียิ่งขึ้นตามความเห็นโดย Wiktor Stribiżewคุณสามารถใช้การจับ 0 เดี่ยวในกลุ่มและทำซ้ำกลุ่มของตัวเองเพื่อจับภาพอินสแตนซ์สุดท้ายของศูนย์

^(0)+$|^0+

การสาธิต Regex


3
ฉันจะใช้^(0)+$|^0+
Wiktor Stribiżew

3
ดูเหมือนว่าsub("^0+(?!$)", "", x, perl=TRUE)จะใช้งานได้
Wiktor Stribiżew

2

regexตัวเลือกอื่น:

^0*(.+)$

นี่คือการสาธิต regex

ใช้base::subใน R:

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

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

นี่คือการสาธิต R

หรือขยายคำตอบของ @ akrun :

sub("^$", "0", sub("^0+", "", c("005", "0AB", "000", "0")), perl = TRUE)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.