Tes jika karakter dalam string

I'm mencoba untuk menentukan apakah sebuah string adalah subset dari string lain. Misalnya:

chars <- "test"
value <- "es"

Saya ingin mengembalikan TRUE jika "nilai" muncul sebagai bagian dari string "karakter". Dalam skenario berikut, saya ingin kembali palsu:

chars <- "test"
value <- "et"
Mengomentari pertanyaan (3)
Larutan

Gunakan grepl fungsi

grepl(value, chars)
# TRUE
Komentar (9)

Jawaban

Menghela napas, butuh waktu 45 menit untuk menemukan jawaban untuk pertanyaan sederhana ini. Jawabannya adalah: grepl(jarum, jerami, tetap=TRUE)

# Correct
> grepl("1+2", "1+2", fixed=TRUE)
[1] TRUE
> grepl("1+2", "123+456", fixed=TRUE)
[1] FALSE

# Incorrect
> grepl("1+2", "1+2")
[1] FALSE
> grepl("1+2", "123+456")
[1] TRUE

Interpretasi

grep ini dinamai linux yang dapat dijalankan, yang itu sendiri merupakan singkatan dari "Global Regular Expression Pedia", itu akan membaca baris dari input dan kemudian mencetaknya jika mereka cocok dengan argumen yang anda berikan. "Global" berarti pertandingan bisa terjadi di mana saja pada baris input, I'll menjelaskan "Ekspresi Reguler" di bawah ini, tapi ide itu's cara yang lebih cerdas untuk mencocokkan string (R panggilan ini "karakter", misal kelas("abc")), dan "Print" karena itu's program baris perintah, memancarkan output berarti cetakan untuk output string.

Sekarang, grep program pada dasarnya adalah sebuah filter, dari baris-baris masukan, untuk jalur output. Dan tampaknya bahwa R's grep fungsi sama akan mengambil sebuah array dari masukan-masukan. Untuk alasan yang sama sekali tidak diketahui untuk saya (saya hanya mulai bermain dengan R sekitar satu jam yang lalu), ini akan menghasilkan sebuah vektor indeks yang cocok, daripada sebuah daftar dari pertandingan-pertandingan.

Tapi, kembali ke pertanyaan awal, apa yang kita benar-benar ingin tahu apakah kita menemukan jarum di tumpukan jerami, yang benar/salah nilai. Mereka tampaknya memutuskan untuk nama fungsi ini grepl, seperti dalam "grep" dengan "Logical" nilai kembali (mereka sebut true dan false nilai-nilai logis, misal kelas(BENAR)).

Jadi, sekarang kita tahu di mana nama tersebut berasal dan apa itu's seharusnya dilakukan. Mari kita kembali ke Ekspresi Reguler. Argumen, meskipun mereka adalah string, mereka digunakan untuk membangun ekspresi reguler (selanjutnya: regex). Regex adalah cara untuk mencocokkan string (jika definisi ini mengganggu anda, biarkan saja). Sebagai contoh, ekspresi reguler a sesuai dengan karakter "a", regex a* sesuai dengan karakter "a" 0 kali atau lebih, dan regex a+ akan cocok dengan karakter "a" 1 kali atau lebih. Oleh karena itu dalam contoh di atas, jarum kami sedang mencari 1+2, ketika diperlakukan sebagai regex, berarti "satu atau lebih 1 diikuti oleh 2"... tetapi kita diikuti oleh plus!

Jadi, jika anda menggunakan grepl tanpa tetap, jarum anda akan secara tidak sengaja menjadi tumpukan jerami, dan itu akan secara tidak sengaja bekerja cukup sering, kita dapat melihat hal ini bahkan bekerja untuk OP's contoh. Tapi yang's laten bug! Kita harus mengatakan itu input string, tidak regex, yang rupanya apa yang fixed untuk. Mengapa tetap? Tidak ada petunjuk, bookmark ini jawaban b/c anda're mungkin akan memiliki untuk mencarinya 5 kali lagi sebelum anda mendapatkannya hafal.

Beberapa pemikiran akhir

Baik kode anda, semakin sedikit sejarah yang harus anda tahu untuk membuat rasa itu. Setiap argumen dapat memiliki setidaknya dua nilai-nilai yang menarik (kalau tidak,'t harus menjadi argumen), dokumen daftar 9 argumen di sini, yang berarti ada's minimal 2^9=512 cara-cara untuk memohon itu, yang's banyak pekerjaan untuk menulis, menguji, dan ingat... memisahkan fungsi-fungsi tersebut (memisahkan mereka, menghapus ketergantungan pada satu sama lain, string hal-hal yang berbeda dari regex hal-hal yang berbeda dari vektor-hal). Beberapa pilihan juga saling eksklusif, don't memberikan pengguna cara yang salah untuk menggunakan kode, yaitu bermasalah doa harus secara struktural tidak masuk akal (seperti melewati sebuah pilihan yang doesn't ada), tidak logis dan tidak masuk akal (di mana anda harus memancarkan peringatan untuk menjelaskannya). Menempatkan secara metaforis: mengganti pintu depan di sisi 10 lantai dengan dinding yang lebih baik dari yang menggantung tanda yang memperingatkan terhadap penggunaannya, tapi lebih baik daripada tidak. Dalam sebuah antarmuka, fungsi mendefinisikan apa argumen harus terlihat seperti, tidak pemanggil (karena pemanggil tergantung pada fungsi, menyimpulkan segala sesuatu yang semua orang mungkin pernah ingin menyebutnya dengan membuat fungsi tergantung pada penelepon, juga, dan jenis siklus ketergantungan akan cepat menyumbat sistem dan tidak pernah memberikan manfaat yang anda harapkan). Menjadi sangat berhati-hati berdalih jenis, it's cacat desain yang hal-hal seperti BENAR dan 0 dan "abc" semua vektor.

Komentar (2)

Anda ingin grepl:

> chars  value  grepl(value, chars)
[1] TRUE
> chars  value  grepl(value, chars)
[1] FALSE
Komentar (0)

Gunakan fungsi ini dari stringi paket:

> stri_detect_fixed("test",c("et","es"))
[1] FALSE  TRUE

Beberapa tolok ukur:


library(stringi)
set.seed(123L)
value 
Komentar (0)

Juga, dapat dilakukan dengan menggunakan "stringr" perpustakaan:

> library(stringr)
> chars  value  str_detect(chars, value)
[1] TRUE

### For multiple value case:
> value  str_detect(chars, value)
[1]  TRUE FALSE  TRUE FALSE  TRUE
Komentar (0)

Hanya dalam kasus anda juga ingin memeriksa apakah string (atau satu set string) mengandung(s) beberapa sub-string, anda juga dapat menggunakan '|' antara dua substring.

>substring="as|at"
>string_vector=c("ass","ear","eye","heat") 
>grepl(substring,string_vector)

Anda akan mendapatkan

[1]  TRUE FALSE FALSE  TRUE

sejak tanggal 1 kata yang memiliki substring "seperti", dan kata terakhir yang berisi substring "di"

Komentar (1)

Gunakan grep atau grepl tapi diketahui dari apakah atau tidak anda ingin menggunakan ekspresi reguler.

Secara default, grep dan terkait mengambil reguler expression ke pertandingan, bukan literal substring. Jika anda're tidak mengharapkan itu, dan anda mencoba untuk mencocokkan pada tidak valid regex, itu doesn't bekerja:

> grep("[", "abc[")
Error in grep("[", "abc[") : 
  invalid regular expression '[', reason 'Missing ']''

Untuk melakukan yang benar substring tes, menggunakan tetap = TRUE.

> grep("[", "abc[", fixed = TRUE)
[1] 1

Jika anda ingin regex, besar, tapi yang's tidak apa-OP yang muncul untuk bertanya.

Komentar (0)

Anda dapat menggunakan grep

grep("es", "Test")
[1] 1
grep("et", "Test")
integer(0)
Komentar (0)