Bagaimana cara menghapus angka nol dari teks alfanumerik?


228

Saya telah melihat pertanyaan tentang bagaimana cara mengawali angka nol di sini di SO. Tapi tidak sebaliknya!

Bisakah kalian menyarankan saya cara menghapus nol terkemuka dalam teks alfanumerik? Apakah ada API bawaan atau apakah saya perlu menulis metode untuk memangkas nol terkemuka?

Contoh:

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

Jawaban:


617

Regex adalah alat terbaik untuk pekerjaan itu; apa yang seharusnya tergantung pada spesifikasi masalah. Berikut ini menghapus nol di depan, tetapi meninggalkannya jika perlu (artinya tidak hanya berubah "0"menjadi string kosong).

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

The ^jangkar akan memastikan bahwa 0+yang cocok adalah pada awal input. The (?!$)Memastikan lookahead negatif yang tidak seluruh string akan dicocokkan.

Uji harness:

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+(?!$)", "") + "]");
}

Lihat juga


21
Terima kasih. Dan Anda telah menguji dengan kejam;) Hebat !! +1 untuk tes.
jai

4
@Reg: Pertanyaan ini tentang Java, bukan JavaScript. Java SE telah memiliki metode String.replaceFirst () sejak versi 1.4.
Jonik

5
menambahkan trim () ke s.replaceFirst ("^ 0 + (?! $)", "") (mis. s.trim (). replaceFirst ("^ 0 + (?! $)", "") akan membantu dalam menghapus ruang empuk!
AVA

2
bukankah regex sedikit mahal untuk tugas sederhana seperti itu?
demongolem

5
Ini tidak berfungsi di Kotlin, Anda harus eksplisit tentang Regex.replaceFirst("^0+(?!$)".toRegex(), "")
mkabatek

100

Anda dapat menggunakan kelas StringUtils dari Apache Commons Lang seperti ini:

StringUtils.stripStart(yourString,"0");

Apakah ini ada masalah dengan "0" saja? @Hamilton Rodrigues
PhoonOne

2
Jika menggunakan ini pada "0" saja, itu mengembalikan "". Jadi peduli apakah ini bukan efek yang diinginkan diperlukan.
DARKpRINCE

Penyebab tervvatifikasi berfungsi untuk kasus penggunaan dalam pertanyaan yang diajukan. Membantu saya di sini juga untuk solusi cepat. Terima kasih!
Gabriel Amazonas Mesquita

32

Bagaimana dengan cara regex:

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

The ^jangkar ke awal dari string (aku mengasumsikan dari konteks string Anda tidak multi-line di sini, jika Anda mungkin perlu untuk melihat ke dalam \Auntuk memulai input daripada awal baris). The 0*berarti nol atau lebih 0karakter (Anda bisa menggunakan 0+juga). The replaceFirsthanya menggantikan semua 0karakter di awal dengan apa-apa.

Dan jika, seperti Vadzim, definisi Anda tentang angka nol di depan tidak termasuk mengubah "0"(atau "000"string serupa) menjadi string kosong (harapan yang cukup rasional), cukup masukkan kembali jika perlu:

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

6
Ada masalah dengan "0" saja.
Vadzim

23

Cara yang jelas tanpa perlu regExp dan perpustakaan eksternal.

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
Meskipun cek Anda untuk ruang tidak sesuai dengan pertanyaan, namun saya pikir jawaban Anda akan mengeksekusi tercepat.
John Fowler

@JohnFowler 10x untuk tangkapan, diperbaiki setelah 2+ tahun
magiccrafter

1
Dan metode ini membutuhkan pengembalian di akhir jika loop hanya menemukan nol. kembali ""; atau kembalikan "0"; jika Anda ingin setidaknya satu nol
slipperyseal

@ Slipperyseal saya membiarkannya terbuka sehingga Anda dapat mengubahnya berdasarkan kebutuhan Anda, tetapi karena orang cenderung menyalin / menempel, itu bukan ide yang buruk untuk selalu memiliki perilaku default. terima kasih atas komentarnya
magiccrafter

14

Agar sesuai dengan jawaban Apache Commons pertama: menggunakan jambu-libraries ( pustaka utilitas Java untuk tujuan umum Google yang menurut saya sekarang harus berada di classpath dari setiap proyek Java non-sepele), ini akan menggunakan CharMatcher :

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

+1, jawaban yang benar untuk proyek apa pun yang menggunakan Guava. (Dan sekarang di 2012 yang harus berarti cukup banyak setiap proyek Java.)
Jonik

1
@Cowan Apakah ini ada masalah dengan "0" saja? Will CharMatcher.is ('0'). TrimLeadingFrom ("0"); Kembalikan "0" atau String kosong?
PhoonOne

@ PhoonOne: Saya baru saja menguji ini; mengembalikan string kosong.
Stephan202

10

Jika Anda menggunakan Kotlin Ini adalah satu-satunya kode yang Anda butuhkan:

yourString.trimStart('0')

5

Anda bisa melakukannya: String s = Integer.valueOf("0001007").toString();


2
Tidak akan menangani alfanumerik.
slaman

4

Gunakan StringUtilskelas Apache Commons :

StringUtils.strip(String str, String stripChars);

2
PERINGATAN! Ini akan menghapus nol awal dan akhir, yang mungkin bukan yang Anda inginkan.
Jens Bannmann

18
Anda dapat menghapus hanya nol yang mengarah menggunakan StringUtils.stripStart ().
Josh Rosen


2

Menggunakan Regexp dengan grup:

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

Menggunakan regex sebagai beberapa jawaban menyarankan adalah cara yang baik untuk melakukan itu. Jika Anda tidak ingin menggunakan regex maka Anda dapat menggunakan kode ini:

String s = "00a0a121";

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

Ini bisa membuat banyak String... gunakan pendekatan magiccrafter sebagai gantinya.
AxelH

1

Saya pikir itu sangat mudah untuk dilakukan. Anda hanya dapat mengulangi string dari awal dan menghapus nol sampai Anda menemukan char tidak nol.

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

Jika Anda (seperti saya) perlu menghapus semua nol terkemuka dari setiap "kata" dalam sebuah string, Anda dapat memodifikasi jawaban @polygenelubricants sebagai berikut:

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

yang mengakibatkan:

3 d0g ss 0 0 0

1

Tanpa menggunakan Regexatau substring()fungsi Stringyang tidak efisien -

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

Anda bisa mengganti "^0*(.*)"ke "$1"dengan regex


1
Satu-satunya masalah yang saya lihat di sini adalah ini mungkin mengganti nol nol '0' menjadi kosong.
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

Jika Anda tidak ingin menggunakan regex atau perpustakaan eksternal. Anda dapat melakukannya dengan "untuk":

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

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

Terlalu banyak yang Stringdihasilkan selama loop ini ... jika ada 1000 0...
AxelH

0

Saya membuat beberapa tes benchmark dan menemukan, bahwa cara tercepat (sejauh ini) adalah solusi ini:

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

Terutama ekspresi reguler sangat lambat dalam iterasi yang panjang. (Saya perlu mencari tahu cara tercepat untuk melakukan batchjob.)


-2

Dan bagaimana dengan hanya mencari karakter non-nol pertama?

[1-9]\d+

Regex ini menemukan digit pertama antara 1 dan 9 diikuti oleh sejumlah digit, jadi untuk "00012345" ia mengembalikan "12345" . Itu dapat dengan mudah diadaptasi untuk string alfanumerik.


Ini tidak akan mengizinkan nol sesudahnya juga.
Nishant Dongare
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.