Як видалити провідні нулі з буквено-цифрового тексту?


228

Я бачив питання про те, як префіксувати нулі тут, в SO. Але не іншим способом!

Ви можете запропонувати мені, як видалити провідні нулі з буквено-цифрового тексту? Чи є вбудовані API чи мені потрібно написати метод обрізки провідних нулів?

Приклад:

01234 converts to 1234
0001234a converts to 1234a
001234-a converts to 1234-a
101234 remains as 101234
2509398 remains as 2509398
123z remains as 123z
000002829839 converts to 2829839

Відповіді:


617

Регекс - найкращий інструмент для роботи; яким він повинен бути, залежить від специфікації проблеми. Далі видаляються початкові нулі, але залишається один, якщо це необхідно (тобто він не просто перетвориться "0"на порожній рядок).

s.replaceFirst("^0+(?!$)", "")

^Якір буде переконатися , що 0+підкріплюються знаходиться на початку введення. В (?!$)Негативні гарантує , що ні щодо подальшого вся рядок буде порівнюватися.

Тестовий джгут:

String[] in = {
    "01234",         // "[1234]"
    "0001234a",      // "[1234a]"
    "101234",        // "[101234]"
    "000002829839",  // "[2829839]"
    "0",             // "[0]"
    "0000000",       // "[0]"
    "0000009",       // "[9]"
    "000000z",       // "[z]"
    "000000.z",      // "[.z]"
};
for (String s : in) {
    System.out.println("[" + s.replaceFirst("^0+(?!$)", "") + "]");
}

Дивитися також


21
Дякую. І ви безжально випробували;) Чудово !! +1 для тестів.
джей

4
@Greg: Це питання стосується Java, а не JavaScript. У Java SE застосовується метод String.replaceFirst () з версії 1.4.
Джонік

5
додавання trim () до s.replaceFirst ("^ 0 + (?! $)", "") (тобто. s.trim (). допоможе замінитиFirst ("^ 0 + (?! $)", "") у видаленні прокладених пробілів!
AVA

2
хіба що регулярне вирівнювання трохи не дороге для такого простого завдання?
demongolem

5
У .replaceFirst("^0+(?!$)".toRegex(), "")
Котліні

100

Ви можете використовувати клас StringUtils від Apache Commons Lang таким чином:

StringUtils.stripStart(yourString,"0");

Чи має це проблема лише з "0"? @Hamilton Rodrigues
PhoonOne

2
Якщо використовувати це лише на "0", воно повертає "". Тож обережно, якщо це не потрібний бажаний ефект.
dARKpRINCE

Обґрунтована причина, що вона працює для випадків використання в заданому питанні. Допомогли мені і тут для швидкого вирішення. Дякую!
Габріель Амазонас Мескіта

32

Як щодо способу регулярного вираження:

String s = "001234-a";
s = s.replaceFirst ("^0*", "");

У ^анкери до початку рядка (я припускаю , що з контексту ваших рядків не багаторядкові тут, в іншому випадку вам , можливо , доведеться дивитися в \Aспершу введення , а не почала рядки). В 0*означає нуль або більше 0символів (ви могли б використовувати 0+, а). replaceFirstПросто замінює всі ці 0символи на початку з нуля.

І якщо, як і Вадим, ваше визначення провідних нулів не включає перетворення "0"(або "000"подібні рядки) у порожній рядок (достатньо раціональне очікування), просто поставте його за потреби:

String s = "00000000";
s = s.replaceFirst ("^0*", "");
if (s.isEmpty()) s = "0";

6
У нього проблеми лише з "0".
Вадим

23

Чіткий спосіб без потреби regExp та будь-яких зовнішніх бібліотек.

public static String trimLeadingZeros(String source) {
    for (int i = 0; i < source.length(); ++i) {
        char c = source.charAt(i);
        if (c != '0') {
            return source.substring(i);
        }
    }
    return ""; // or return "0";
}

1
Хоча ваша перевірка місця не відповідає, але я думаю, що ваша відповідь виконала б найшвидше.
Джон Фоулер

@JohnFowler 10x за улов, зафіксований через 2+ роки
magiccrafter

1
І метод потребує повернення в кінці, якщо цикл знаходить лише нулі. повернути ""; або повернути "0"; якщо хочете хоча б один нуль
слизький

@slipperyseal Я залишив його відкритим, щоб ви могли змінити його залежно від ваших потреб, але оскільки люди прагнуть копіювати / вставляти, це не погана ідея завжди мати поведінку за замовчуванням. дякую за коментар
magiccrafter

14

Щоб відповісти Apache Commons відповіді Thelost: використовуючи бібліотеки guava (загальна бібліотека Java утиліти Java, яку я б стверджував, тепер слід перекладати на будь-який нетривіальний проект Java), це використовує CharMatcher :

CharMatcher.is('0').trimLeadingFrom(inputString);

+1, правильна відповідь для будь-якого проекту, що використовує Guava. (А тепер у 2012 році це мало б означати будь-який проект Java.)
Jonik

1
@Cowan Чи має це проблема лише з "0"? Will CharMatcher.is ('0'). TrimLeadingFrom ("0"); Повернути "0" чи порожню рядок?
PhoonOne

@PhoonOne: я щойно це перевірив; він повертає порожню рядок.
Stephan202


5

Ви можете просто зробити: String s = Integer.valueOf("0001007").toString();


2
Не впорається з буквено-цифрових значень.
вбивця

4

Використовуйте StringUtilsклас Apache Commons :

StringUtils.strip(String str, String stripChars);

2
УВАГА! Це позбавить початкових і кінцевих нулів, що може бути не тим, що ви хочете.
Єнс Банманн

18
За допомогою StringUtils.stripStart () можна зняти лише провідні нулі.
Джош Розен


2

Використання Regexp з групами:

Pattern pattern = Pattern.compile("(0*)(.*)");
String result = "";
Matcher matcher = pattern.matcher(content);
if (matcher.matches())
{
      // first group contains 0, second group the remaining characters
      // 000abcd - > 000, abcd
      result = matcher.group(2);
}

return result;

2

Використання регулярного вираження, як підказують деякі відповіді - хороший спосіб зробити це. Якщо ви не хочете використовувати регулярний вираз, тоді ви можете використовувати цей код:

String s = "00a0a121";

while(s.length()>0 && s.charAt(0)=='0')
{
   s = s.substring(1); 
}

Це могло б створити багато String... замість цього використовувати підказку magiccrafter .
AxelH

1

Я думаю, що це так просто зробити. Ви можете просто перевести цикл на рядок із самого початку та видалити нулі, поки не знайдете нульовий знак.

int lastLeadZeroIndex = 0;
for (int i = 0; i < str.length(); i++) {
  char c = str.charAt(i);
  if (c == '0') {
    lastLeadZeroIndex = i;
  } else {
    break;
  }
}

str = str.subString(lastLeadZeroIndex+1, str.length());

1

Якщо вам (як і мені) потрібно видалити всі провідні нулі з кожного "слова" в рядку, ви можете змінити відповідь @polygenelubricants на таке:

String s = "003 d0g 00ss 00 0 00";
s.replaceAll("\\b0+(?!\\b)", "");

що призводить до:

3 d0g ss 0 0 0

1

Без використання Regexабо substring()функції, на Stringякій буде неефективно -

public static String removeZero(String str){
        StringBuffer sb = new StringBuffer(str);
        while (sb.length()>1 && sb.charAt(0) == '0')
            sb.deleteCharAt(0);
        return sb.toString();  // return in String
    }

0

Ви можете замінити "^0*(.*)"на "$1"регекс


1
Єдине питання, яке я бачу тут, це те, що це може замінити порожній нуль '0' на порожній.
Діліпкумар J

0
       String s="0000000000046457657772752256266542=56256010000085100000";      
    String removeString="";

    for(int i =0;i<s.length();i++){
      if(s.charAt(i)=='0')
        removeString=removeString+"0";
      else 
        break;
    }

    System.out.println("original string - "+s);

    System.out.println("after removing 0's -"+s.replaceFirst(removeString,""));

0

Якщо ви не хочете використовувати регулярний або зовнішню бібліотеку. Ви можете зробити з "за":

String input="0000008008451"
String output = input.trim();
for( ;output.length() > 1 && output.charAt(0) == '0'; output = output.substring(1));

System.out.println(output);//8008451

Забагато Stringгенерується під час цього циклу ... якщо є 1000 0...
AxelH

0

Я зробив кілька контрольних тестів і виявив, що найшвидший спосіб (на сьогоднішній день) це рішення:

    private static String removeLeadingZeros(String s) {
      try {
          Integer intVal = Integer.parseInt(s);
          s = intVal.toString();
      } catch (Exception ex) {
          // whatever
      }
      return s;
    }

Особливо регулярні вирази дуже повільні при тривалій ітерації. (Мені потрібно було знайти найшвидший спосіб для групової роботи.)


-2

А як бути з пошуком першого ненульового персонажа?

[1-9]\d+

Цей регулярний вираз знаходить першу цифру між 1 і 9, а потім будь-яку кількість цифр, тому для "00012345" він повертає "12345" . Його можна легко адаптувати для буквено-цифрових струн.


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