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"

Цей інший потік пояснює, як робити те, що я хочу, але я не думаю, що я отримую синтаксис цілком правильним, застосовуючи рішення в R. якщо вони справді працювали).

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"

Який правильний регулярний вираз в R, щоб отримати те, що я хочу?

Відповіді:


6

Ви можете видалити всі нулі з початку рядка, але не останню:

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

Дивіться демонстрацію регексу .

Деталі

  • ^ - початок рядка
  • 0+ - одна або кілька нулів
  • (?!$) - негативний підказник, який не відповідає матчу, якщо є кінець позиції рядка праворуч від поточного місця розташування

Дивіться демонстрацію R :

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

1
regexновачок. Яка різниця в продуктивності (або інших уподобаннях) між вашим малюнком і цим ^0*(.+)$чи ^0+(.+)$?
M--

2
@ M - це різні схеми, рекомендується лише порівнювати продуктивність еквівалентних регулярних виразів. Ваші трохи неефективні, як вони .можуть відповідати, 0і обидва суміжні зразки нескінченно кількісно визначені, але просто крихітні.
Wiktor Stribiżew

4

Ми можемо додати ще одне умова за допомогою зворотного зразка, щоб перевірити наявність будь-яких ненульових значень після однієї або декількох нулів ( 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в якому разі не гуру, але пошукові округи не ефективні, чи не так? Оскільки у вас є два, subви можете видалити всі провідні нулі та замінити ""їх 0? sub("^$", "0", sub("^0+", "", v1), perl = TRUE)
M--

2
@ M-- Це було б не настільки ефективно, але я використовував його для того самого коду, що і ОП
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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.