Excel: karakter / string terakhir cocok dalam sebuah string

187

Apakah ada cara yang efisien untuk mengidentifikasi kecocokan karakter / string terakhir dalam string menggunakan fungsi dasar? Yaitu bukan karakter / string terakhir dari string, tetapi posisi kemunculan karakter / string terakhir dalam sebuah string. Searchdan findkeduanya bekerja dari kiri ke kanan jadi saya tidak bisa memikirkan cara menerapkannya tanpa algoritma rekursif yang panjang. Dan solusi ini sekarang tampaknya sudah usang.

geotheory
sumber
3
Karena saya ingin posisi instance terakhir mis. Periode "." dalam string "one.two.three.four"
geotheory
6
Lucu bagaimana pembacaan yang salah dari pertanyaan mengumpulkan suara
geotheory
1
Saya akan mengatakan melihatnya dari sudut pandang lain, itu berarti orang lain juga tidak mengerti apa yang Anda maksud dalam pertanyaan Anda dan jadi sarannya adalah solusi yang tepat ... Bahkan jawaban yang Anda pilih dimulai dengan "Saya pikir saya dapatkan apa yang Anda maksudkan "... Bukan kritik, melainkan permintaan untuk bertujuan membuat pertanyaan Anda lebih mudah dipahami untuk membantu orang menjawab lebih mudah.
John Bustos
Saya seharusnya menambahkan contoh ke pertanyaan, tapi saya pikir ada cukup untuk membedakan ini dari permintaan tentang karakter akhir dari string: searchdan findkeduanya konten string permintaan , 'cocok' adalah istilah standar, ditambah contoh yang ditautkan.
geotheory
kemungkinan duplikat dari Cara mengekstrak substring terakhir dari kolom Excel?
Jean-François Corbett

Jawaban:

1

Dengan versi excel yang lebih baru, muncul fungsi baru dan metode baru. Meskipun dapat direplikasi dalam versi yang lebih lama (namun saya belum pernah melihatnya sebelumnya), ketika seseorang memiliki Excel O365, ia dapat menggunakan:

=MATCH(2,1/(MID(A1,SEQUENCE(LEN(A1)),1)="Y"))

Ini juga dapat digunakan untuk mengambil posisi terakhir dari substring (tumpang tindih):

=MATCH(2,1/(MID(A1,SEQUENCE(LEN(A1)),2)="YY"))

| Value  | Pattern | Formula                                        | Position |
|--------|---------|------------------------------------------------|----------|
| XYYZ   | Y       | =MATCH(2,1/(MID(A2,SEQUENCE(LEN(A2)),1)="Y"))  | 3        |
| XYYYZ  | YY      | =MATCH(2,1/(MID(A3,SEQUENCE(LEN(A3)),2)="YY")) | 3        |
| XYYYYZ | YY      | =MATCH(2,1/(MID(A4,SEQUENCE(LEN(A4)),2)="YY")) | 4        |

Sementara ini keduanya memungkinkan kita untuk tidak lagi menggunakan karakter pengganti yang sewenang-wenang dan memungkinkan pola yang tumpang tindih, "downside" adalah penggunaan array.


Catatan: Anda bisa memaksa perilaku yang sama di versi Excel yang lebih lama melalui keduanya

=MATCH(2,1/(MID(A2,ROW(A1:INDEX(A:A,LEN(A2))),1)="Y"))

Dimasukkan melalui CtrlShiftEnter, atau menggunakan inline INDEXuntuk menyingkirkan persimpangan implisit:

=MATCH(2,INDEX(1/(MID(A2,ROW(A1:INDEX(A:A,LEN(A2))),1)="Y"),))
JvdV
sumber
1
Saya pikir ini mewarisi kutu sekarang, meskipun penghargaan historis penuh milik solusi lama @ tigerembung stackoverflow.com/a/18617720/1156245
geotheory
Catatan: Sementara saran saya akan menang di golf kode samar, penggunaan array tidak selalu dianjurkan ketika digunakan dalam jumlah besar. Namun, ada manfaat lain yang saya coba sebutkan secara eksplisit. Ini membuat jawaban oleh @Tigerewati sama relevannya seperti sebelumnya!
JvdV
345

Saya rasa saya mengerti maksud Anda. Katakanlah misalnya Anda menginginkan \ paling kanan di string berikut (yang disimpan dalam sel A1):

Drive: \ Folder \ SubFolder \ Filename.ext

Untuk mendapatkan posisi yang terakhir \, Anda akan menggunakan rumus ini:

=FIND("@",SUBSTITUTE(A1,"\","@",(LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))/LEN("\")))

Itu memberitahu kita yang paling kanan \ adalah pada karakter 24. Ia melakukan ini dengan mencari "@" dan mengganti "\" terakhir dengan "@". Ini menentukan yang terakhir dengan menggunakan

(len(string)-len(substitute(string, substring, "")))\len(substring)

Dalam skenario ini, substring hanyalah "\" yang memiliki panjang 1, sehingga Anda dapat meninggalkan divisi di akhir dan cukup gunakan:

=FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))

Sekarang kita bisa menggunakannya untuk mendapatkan path folder:

=LEFT(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))))

Inilah jalur folder tanpa trailing \

=LEFT(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))-1)

Dan untuk mendapatkan hanya nama file:

=MID(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))+1,LEN(A1))

Namun, di sini adalah versi alternatif untuk mendapatkan semuanya di sebelah kanan dari contoh terakhir dari karakter tertentu. Jadi, dengan menggunakan contoh yang sama, ini juga akan mengembalikan nama file:

=TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",LEN(A1))),LEN(A1)))
tigerewati
sumber
24
kepala berputar; head spinnning; kepala berputar; "ok - jangan mau menggunakan ini tanpa memahaminya, jadi ... eh huh, ok, uh huh ... tunggu apa? whoah! benarkah? itu jenius! Aku merasa yakin aku tidak akan memikirkan itu dalam beberapa jam kalau bukan berhari-hari atau berminggu-minggu! " - +1, sayangnya, karena +5 atau +10 sulit dilakukan sendiri --- jika-Anda-terjebak-penjelasan: (menggunakan contoh) SUBSTITUTEsemua (3) contoh \tanpa apa-apa (memperpendek panjang string) oleh 3) -> bahwa \(yang ke-3) adalah yang terakhir; gantikan dengan sesuatu yang unik dan FINDposisi karakter unik itu ... luar biasa ... terima kasih!
Code Jockey
7
Itu pintar. Hanya perlu berhati-hati bahwa sel tersebut belum mengandung '@' jika tidak, Anda perlu sub dengan yang lain. Anda dapat memeriksa menggunakan =ISNUMBER(SEARCH("@",A1)), seperti yang diusulkan oleh @ gwin003 .
geotheory
3
Opsi terakhir Anda untuk mengekstraksi segala sesuatu di sebelah kanan dari kejadian terakhir sangat dihargai karena sebagian besar waktu saya telah mencari "kemunculan terakhir dari string x dalam string y", tujuan akhir saya benar-benar adalah untuk mendapatkan semuanya ke hak kejadian terakhir itu.
SSilk
1
Mengapa 99? Apakah Anda hanya mengasumsikan panjang berbagai string ini kurang dari 99? Lihat jawaban ini dan jawaban ini yang tidak membuat asumsi seperti itu.
Jean-François Corbett
2
Alih-alih "@", saya menggunakan CHAR (9) (karakter tab), karena data saya awalnya berasal dari file yang dibatasi-tab, dan saya dijamin tidak akan ada dalam data saya.
Josiah Yoder
28

Bagaimana dengan membuat fungsi khusus dan menggunakannya dalam rumus Anda? VBA memiliki fungsi bawaan InStrRev,, yang melakukan persis seperti yang Anda cari.

Masukkan ini ke modul baru:

Function RSearch(str As String, find As String)
    RSearch = InStrRev(str, find)
End Function

Dan fungsi Anda akan terlihat seperti ini (dengan asumsi string asli dalam B1):

=LEFT(B1,RSearch(B1,"\"))
Keith Rust
sumber
2
Ini adalah solusi yang sangat sederhana tetapi bekerja. Jika Anda dapat menggunakan beberapa VBA dalam proyek Anda, gunakan yang ini.
Patrick Hofman
7

tiger[ dan Jean-François Corbett menyarankan untuk menggunakan rumus ini untuk menghasilkan string tepat dari kemunculan terakhir karakter "\"

=TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",LEN(A1))),LEN(A1)))

Jika karakter yang digunakan sebagai pemisah adalah spasi, "", maka rumusnya harus diubah menjadi:

=SUBSTITUTE(RIGHT(SUBSTITUTE(A1," ",REPT("{",LEN(A1))),LEN(A1)),"{","")

Tidak perlu disebutkan, karakter "{" dapat diganti dengan karakter apa pun yang tidak "normal" akan muncul di teks untuk diproses.

Eugen Sumindan
sumber
Saya menemukan solusi ini jauh lebih elegan dan mudah dimengerti. Juga jika Anda mengalikan LEN (A1) dengan angka yang Anda dapatkan dari kejadian terakhir, asalkan string asli Anda tidak mengandung spasi (yang merupakan kasus bagi saya)
Zlatin Zlatev
4

Baru saja menemukan solusi ini, tidak perlu VBA;

Temukan kejadian terakhir "_" dalam contoh saya;

=IFERROR(FIND(CHAR(1);SUBSTITUTE(A1;"_";CHAR(1);LEN(A1)-LEN(SUBSTITUTE(A1;"_";"")));0)

Dijelaskan dalam ke luar;

SUBSTITUTE(A1;"_";"") => replace "_" by spaces
LEN( *above* ) => count the chars
LEN(A1)- *above*  => indicates amount of chars replaced (= occurrences of "_")
SUBSTITUTE(A1;"_";CHAR(1); *above* ) => replace the Nth occurence of "_" by CHAR(1) (Nth = amount of chars replaced = the last one)
FIND(CHAR(1); *above* ) => Find the CHAR(1), being the last (replaced) occurance of "_" in our case
IFERROR( *above* ;"0") => in case no chars were found, return "0"

Semoga ini bermanfaat.

Tuan Thee
sumber
3

Anda bisa menggunakan fungsi ini saya buat untuk menemukan contoh terakhir dari string dalam sebuah string.

Memang rumus Excel yang diterima berfungsi, tetapi terlalu sulit untuk dibaca dan digunakan. Pada titik tertentu, Anda harus membelah diri menjadi potongan-potongan yang lebih kecil agar dapat dirawat. Fungsi saya di bawah ini dapat dibaca, tetapi itu tidak relevan karena Anda menyebutnya dalam rumus menggunakan parameter bernama. Ini membuatnya mudah digunakan.

Public Function FindLastCharOccurence(fromText As String, searchChar As String) As Integer
Dim lastOccur As Integer
lastOccur = -1
Dim i As Integer
i = 0
For i = Len(fromText) To 1 Step -1
    If Mid(fromText, i, 1) = searchChar Then
        lastOccur = i
        Exit For
    End If
Next i

FindLastCharOccurence = lastOccur
End Function

Saya menggunakannya seperti ini:

=RIGHT(A2, LEN(A2) - FindLastCharOccurence(A2, "\"))
Michael Z.
sumber
2

Mempertimbangkan bagian dari Komentar yang dibuat oleh @Silk tujuan akhir saya benar-benar adalah untuk mendapatkan segalanya dengan benar bahwa kejadian terakhir pendekatan alternatif dengan formula yang sangat sederhana adalah menyalin kolom (katakanlah A) string dan pada salinan (katakanlah ColumnB) terapkan Find and Replace. Misalnya mengambil contoh:Drive:\Folder\SubFolder\Filename.ext

Menemukan apa

Ini mengembalikan apa yang tersisa (di sini Filename.ext) setelah instance terakhir dari karakter apa pun yang dipilih (di sini \) yang terkadang merupakan tujuan dan memfasilitasi menemukan posisi karakter seperti terakhir dengan formula pendek seperti:

=FIND(B1,A1)-1
kacang
sumber
1

Saya agak terlambat ke pesta, tapi mungkin ini bisa membantu. Tautan dalam pertanyaan memiliki rumus yang serupa, tetapi milik saya menggunakan pernyataan IF () untuk menghilangkan kesalahan.

Jika Anda tidak takut dengan Ctrl + Shift + Enter, Anda dapat melakukannya dengan cukup baik dengan rumus array.

String (dalam sel A1): "one.two.three.four"

Rumus:

{=MAX(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)))}  use Ctrl+Shift+Enter

Hasil: 14

Pertama,

ROW($1:$99)

mengembalikan array bilangan bulat 1-99: {1,2,3,4,...,98,99}.

Lanjut,

MID(A1,ROW($1:$99),1)

mengembalikan array string 1-panjang yang ditemukan di string target, lalu mengembalikan string kosong setelah panjang string target tercapai: {"o","n","e",".",..."u","r","","",""...}

Lanjut,

IF(MID(I16,ROW($1:$99),1)=".",ROW($1:$99))

membandingkan setiap item dalam array dengan string "." dan mengembalikan indeks karakter dalam string atau FALSE:{FALSE,FALSE,FALSE,4,FALSE,FALSE,FALSE,8,FALSE,FALSE,FALSE,FALSE,FALSE,14,FALSE,FALSE.....}

Terakhir,

=MAX(IF(MID(I16,ROW($1:$99),1)=".",ROW($1:$99)))

mengembalikan nilai maksimum array: 14

Kelebihan formula ini adalah pendek, relatif mudah dipahami, dan tidak memerlukan karakter unik.

Kekurangannya adalah penggunaan Ctrl + Shift + Enter dan batasan panjang string. Ini dapat dikerjakan dengan variasi yang ditunjukkan di bawah ini, tetapi variasi itu menggunakan fungsi OFFSET () yang merupakan fungsi volatil (baca: lambat).

Tidak yakin berapa kecepatan rumus ini vs. yang lain.

Variasi:

=MAX((MID(A1,ROW(OFFSET($A$1,,,LEN(A1))),1)=".")*ROW(OFFSET($A$1,,,LEN(A1)))) works the same way, but you don't have to worry about the length of the string

=SMALL(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)),2) determines the 2nd occurrence of the match

=LARGE(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)),2) determines the 2nd-to-last occurrence of the match

=MAX(IF(MID(I16,ROW($1:$99),2)=".t",ROW($1:$99))) matches a 2-character string **Make sure you change the last argument of the MID() function to the number of characters in the string you wish to match!
Stadem
sumber
0

Cara sederhana untuk melakukannya di VBA adalah:

YourText = "c:\excel\text.txt"
xString = Mid(YourText, 2 + Len(YourText) - InStr(StrReverse(YourText), "\" ))
Landelin Delcoucq
sumber
0

Sangat terlambat ke pesta, tetapi solusi sederhana menggunakan VBA untuk membuat fungsi kustom.

Tambahkan fungsi ke VBA di Buku Kerja, Lembar Kerja, atau Modul VBA

Function LastSegment(S, C)
    LastSegment = Right(S, Len(S) - InStrRev(S, C))
End Function

Kemudian formula sel

=lastsegment(B1,"/")

dalam sel dan string yang akan dicari di sel B1 akan mengisi sel dengan teks yang mengekor "/" terakhir dari sel B1. Tidak ada batasan panjang, tidak ada rumus yang tidak jelas. Satunya downside yang bisa saya pikirkan adalah perlunya buku kerja yang didukung makro.

Fungsi VBA pengguna apa pun dapat dipanggil dengan cara ini untuk mengembalikan nilai ke rumus sel, termasuk sebagai parameter ke fungsi Excel bawaan.

Jika Anda akan menggunakan fungsinya dengan berat, Anda ingin memeriksa case ketika karakter tidak ada dalam string, maka string kosong, dll.

pengguna8512894
sumber
0

Sel A1 = find/the/position/of/the last slash

Cara mudah untuk melakukannya adalah membalikkan teks dan kemudian menemukan garis miring pertama seperti biasa. Sekarang Anda bisa mendapatkan panjang teks lengkap dikurangi angka ini.

Seperti itu:

=LEN(A1)-FIND("/",REVERSETEXT(A1),1)+1

Ini mengembalikan 21, posisi yang terakhir /

Richard
sumber
REVERSETEXTbukan formula Excel standar
d219