Jawaban:
Anda mencari pasangan yang tidak serakah (atau malas). Untuk mendapatkan kecocokan tidak serakah dalam ekspresi reguler, Anda perlu menggunakan pengubah ?
setelah pengukur. Misalnya, Anda dapat mengubah .*
ke .*?
.
Secara default grep
tidak mendukung pengubah non-serakah, tetapi Anda dapat menggunakan grep -P
sintaks Perl.
.
untuk mencocokkan baris baru disebut DOTALL atau mode single-line ; Ruby adalah satu-satunya yang menyebutnya multiline . Dalam rasa lain, multiline adalah mode yang memungkinkan jangkar ( ^
dan $
) cocok dengan batas garis. Ruby tidak memiliki mode yang sama karena di Ruby mereka selalu bekerja seperti itu.
-P
adalah benar-benar baru pada saya, saya dengan senang hati telah pergi selama bertahun-tahun, dan hanya menggunakan -E
... bertahun-tahun yang terbuang sia-sia! - Catatan untuk diri sendiri: Baca kembali halaman manual sebagai (bahkan lebih!) Hal biasa, Anda tidak pernah mencerna cukup banyak saklar dan opsi.
grep
tidak mendukung -P
, tetapi jika Anda menggunakan egrep
Anda dapat menggunakan .*?
pola untuk mencapai hasil yang sama. egrep -o 'start.*?end' text.html
-P
tetapi -E
akan memanggil egrep
karena itu disarankan .*?
berfungsi dengan baik.
Sebenarnya .*?
satu - satunya yang berfungsi di perl
. Saya tidak yakin apa yang setara dengan grep diperpanjang sintaks regexp akan. Untungnya Anda dapat menggunakan sintaks perl dengan grep sehingga grep -P
akan bekerja tetapi grep -E
yang sama egrep
tidak akan bekerja (itu akan serakah).
Lihat juga: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html
grep -P
tidak bekerja di GNU grep 2.9 - hanya mencobanya (tidak error, hanya diam-diam tidak menerapkan ?
. Intertestly juga tidak kelas misalnya:env|grep '[^\=]*\='
grep -P
opsi atau pgrep
perintah di Darwin / OS X 10.8 Mountain Lion, tetapi egrep
berfungsi dengan baik.
pgrep
perintah pada kotak OS X 10.9 saya, tetapi ini adalah program yang sama sekali berbeda yang tujuannya adalah untuk "mencari atau memberi sinyal proses dengan nama".
Grep saya yang berfungsi setelah mencoba hal-hal di utas ini:
echo "hi how are you " | grep -shoP ".*? "
Pastikan Anda menambahkan spasi ke setiap baris Anda
(Punyaku adalah pencarian baris demi baris untuk meludahkan kata-kata)
-shoP
mnemonic yang bagus :)
echo "bbbbb" | grep -shoP 'b.*?b'
adalah sedikit pengalaman belajar. Satu-satunya hal yang berhasil bagi saya dalam hal malas secara eksplisit juga.
grep
Untuk pertandingan non-serakah di grep
Anda bisa menggunakan kelas karakter yang dinegasikan. Dengan kata lain, cobalah untuk menghindari wildcard.
Misalnya, untuk mengambil semua tautan ke file jpeg dari konten halaman, Anda akan menggunakan:
grep -o '"[^" ]\+.jpg"'
Untuk menangani beberapa saluran, pipa input xargs
terlebih dahulu. Untuk kinerja, gunakan ripgrep
.
Jawaban singkatnya menggunakan ekspresi reguler berikutnya:
(?s)<car .*? model=BMW .*?>.*?</car>
Jawaban (sedikit) yang lebih rumit adalah:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
Ini memungkinkan untuk mencocokkan car1 dan car2 dalam teks berikut
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
Maaf saya terlambat 9 tahun, tapi ini mungkin berhasil untuk pemirsa pada tahun 2020.
Jadi misalkan Anda memiliki garis seperti "Hello my name is Jello"
. Sekarang Anda ingin menemukan kata-kata yang dimulai dengan 'H'
dan diakhiri dengan 'o'
, dengan sejumlah karakter di antaranya. Dan kami tidak ingin kalimat, kami hanya ingin kata-kata. Jadi untuk itu kita bisa menggunakan ekspresi:
grep "H[^ ]*o" file
Ini akan mengembalikan semua kata. Cara kerjanya adalah: Ini akan memungkinkan semua karakter alih-alih karakter spasi di antaranya, dengan cara ini kita dapat menghindari beberapa kata di baris yang sama.
Sekarang Anda dapat mengganti karakter spasi dengan karakter lain yang Anda inginkan. Misalkan baris awal tadi "Hello-my-name-is-Jello"
, maka Anda bisa mendapatkan kata-kata menggunakan ekspresi:
grep "H[^-]*o" file
Saya tahu bahwa ini sedikit posting yang sudah mati, tetapi saya perhatikan bahwa ini berhasil. Itu menghapus pembersihan dan pembersihan dari output saya.
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20