Saya mencari metode untuk mencetak angka terpanjang dalam sebuah string.
Misalnya: Jika saya memiliki string
212334123434test233
bagaimana saya bisa mencetak
212334123434
?
Catatan: Saya mencari urutan angka terus menerus terpanjang, bukan untuk nilai numerik yang lebih tinggi.
Sunting: Terima kasih atas jawabannya, semuanya. Tanggapan atas pertanyaan ini sangat luar biasa. Saya menandai posting @ HaukeLaging sebagai jawaban yang diterima karena sangat cocok dengan kasus spesifik saya, tetapi saya ingin menunjukkan bahwa semua jawaban sama-sama valid. Selalu luar biasa memiliki beberapa opsi berbeda untuk menyelesaikan masalah.
text-processing
sed
awk
Glutanimate
sumber
sumber
Jawaban:
sumber
Saya percaya Anda dapat melakukan ini dengan hanya
grep
,sort
dantail
juga. Berikut adalah beberapa contoh string.Di mana
<str>
string kami sedang dipertanyakan.Contoh
Sekarang jika saya menjalankan ini melalui
grep ...
perintah saya pada gilirannya.Pendekatan ini bekerja dengan memilih semua substring yang merupakan urutan digit. Kami kemudian mengurutkan output ini secara numerik,,
sort -n
dan kemudian mengambil nilai terakhir dalam daftar, menggunakantail -1
. Ini akan menjadi substring terpanjang.Anda dapat melihat cara kerjanya dengan
tail -1
melepas dan menjalankan kembali salah satu contoh:String yang dimulai dengan nol
Pendekatan di atas berfungsi untuk setiap situasi yang bisa saya bayangkan kecuali satu. @terdon disebutkan dalam obrolan skenario ini yang menggagalkan pendekatan di atas.
Jadi untuk menghadapi ini, Anda perlu sedikit mengubah taktik. Kernel dari pendekatan di atas masih dapat ditingkatkan, namun kita perlu menyuntikkan jumlah karakter ke dalam hasil juga. Ini memberikan kemampuan untuk mengurutkan hasil berdasarkan jumlah karakter dalam string & nilainya.
Hasil:
Anda bisa menyingkat sedikit ini dengan memanfaatkan kemampuan Bash untuk menentukan panjang variabel yang digunakan
${#var}
.Menggunakan `grep -P
Saya memilih untuk menggunakan di
grep -P ...
atas karena saya, sebagai pengembang Perl, menyukai sintaksis kelas untuk mengatakan semua digit seperti::\d+
, bukannya[[:digit:]]\+
atau[0-9]\+
. Tetapi untuk masalah khusus ini tidak terlalu dibutuhkan. Anda bisa dengan mudah menukar yanggrep
saya gunakan seperti ini:Sebagai contoh:
sumber
${#i}
untuk mendapatkan panjang string dapat menghemat panggilan Andawc
, jika Anda ingin menggunakan bash-spesifikgrep -o "[0-9]\+"
sebagai gantinyagrep -oP "\d+"
Solusi di
perl
:Referensi
sumber
Menggunakan python dengan string yang diteruskan pada commandline dan dengan asumsi Anda menginginkan urutan pertama dari panjang maksimum:
sumber
python -c "import re,sys; print max(re.split(r'\D+', sys.argv[1]), key=len)"
Berikut adalah pendekatan Perl lain yang dapat menangani desimal serta bilangan bulat:
Perhatikan bahwa tidak ada jawaban yang sejauh ini diposting akan berurusan dengan desimal dan karena Anda menentukan bahwa Anda ingin jumlah terpanjang dan bukan angka terbesar secara numerik, saya menganggap Anda benar - benar membutuhkan desimal.
Penjelasan
perl -lne
:-n
Sarana "baca baris input demi baris, dan jalankan skrip yang diberikan-e
olehnya". The-l
menambahkan baris baru untuk setiapprint
panggilan (dan hal-hal lain tidak relevan di sini).while(/([\d.]+)/g)
: iterate melalui semua angka (\d
berarti[0-9]
, sehingga[\d.]
akan cocok dengan angka dan.
. Jika Anda juga ingin menemukan angka negatif, tambahkan-
. Tanda kurung menangkap string yang cocok seperti$1
yang digunakan pada langkah berikutnya.$max=$1 if length($1) > length($max)
: Jika panjang pertandingan saat ini lebih besar dari yang terpanjang sejauh ini ($max
) simpan pertandingan sebagai$max
.print $max
: cetak string angka terpanjang yang ditemukan. Ini akan dieksekusi setelah loop sementara selesai, jadi setelah semua angka ditemukan.sumber
\D(\d+(?:\.\d+)?)\D
sebagai gantinya.\D
jangkar ....
seperti pada alamat IP.Diberikan
lalu di bash
Solusi bash yang mungkin lebih murni menggunakan array yang dibangun dengan mengganti karakter non-digit dalam string dengan spasi putih, menggantikan grep
sumber
Membangun jawaban dari @mikeserv, berikut adalah alternatif lain. Ini mengekstrak angka (per metode mikeserv), lalu mengurutkannya dalam urutan numerik dan mengambil yang terakhir. Kecuali nol terkemuka, ini akan memberi Anda jumlah terbesar (tidak memperhitungkan tanda):
sumber
set -- $(echo $str | tr ... ) ; b=${#1} ; for d ; do [ ${#d} -gt $b ] && b=${#d} n=$d ; done ; echo $n
tr
, saya tidak akan menyimpan dendam jika Anda memasukkan hal di atas. Mungkinsort
lebih cepat, tetapi, sekali lagi, menunggu aliran berakhir sama dengan$(subshell)
. Saya tidak tahu Bagaimanapun juga, jawaban Anda sudah merupakan jawaban yang sangat baik, tetapi jika Anda ingin menambahkan lingkaran shell di atas, jangan ragu-ragu. Ngomong-ngomong - itu mungkin bisa Anda lakukan tanpasort
sama sekali dengan sedikit penanganan kreatifwc -L
dantee
dalam aliran ... Saya sudah selesai dengan pertanyaan ini - Saya malu.tr
keluar dari subkulit dan dihilangkanprintf
. Lakukan saja'0-9' '\n'
.bash dan semacam GNU
sumber
Gunakan karakter non-numerik untuk memisahkan string, dan temukan urutan terpanjang atau nilai numerik terbesar (untuk nomor dengan panjang yang sama) dengan operator ternary.
Anda juga dapat mengatur pemisah rekaman awk (
RS
) menjadi string karakter non-numerik:sumber
RS = '[^0-9]+'
dan menggunakan loop bawaan Awk?echo "212334123434test233" | awk -v RS='[^0-9]+' 'length(longest) < length($0) {longest = $0};END{print longest}' 212334123434
RS
variabel, saya harus mengakui ini adalah pertama kalinya saya melihatnya. Anda memiliki lebih banyak tips untuk ditawarkanawk
daripada yang saya lakukan hahaha!