Как убрать начальные нули из буквенно-цифрового текста?


229

Я видел вопросы о том, как префиксировать нули здесь, в 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

Ответы:


618

Regex - лучший инструмент для работы; что это должно быть, зависит от спецификации проблемы. Следующее удаляет начальные нули, но оставляет один при необходимости (то есть он не просто превратится "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
@ Грег: Этот вопрос касается Java, а не JavaScript. Java SE имеет метод String.replaceFirst () начиная с версии 1.4.
Джоник

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

2
не слишком ли дорого регулярное выражение для такой простой задачи?
демонголем

5
Это не работает в Kotlin, вы должны быть откровенны в отношении Regex.replaceFirst("^0+(?!$)".toRegex(), "")
mkabatek

101

Вы можете использовать класс StringUtils из Apache Commons Lang следующим образом:

StringUtils.stripStart(yourString,"0");

У этого есть проблема с одним только "0"? @Hamilton Rodrigues
PhoonOne

2
Если использовать это только на «0», он возвращает «». Поэтому будьте осторожны, если это не требуемый эффект.
ТЕЧЕНИЕ ПРИНЦА 21.10.15

Прибалтийская причина, это работает для случаев использования в заданном вопросе. Помог мне и здесь для быстрого решения. Спасибо!
Габриэль Амазонас Мескита

32

Как насчет регулярного выражения:

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

В ^анкеры к началу строки (я предполагаю , что из контекста ваших строк не многострочные здесь, в противном случае вам , возможно , придется смотреть в \Aдля начала ввода , а не начала строки). В 0*означает ноль или более 0символов (вы могли бы использовать 0+, а). The replaceFirstJust заменяет все эти 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

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

14

Чтобы перейти к ответу Apache Commons thelost: используя guava-библиотеки (универсальная служебная библиотека Java от Google, которая, я бы сказал, должна теперь находиться на пути к классам любого нетривиального 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
Не буду обрабатывать буквенно-цифровые.
Slaman

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» на пробел.
Dilipkumar 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.