[Hỏi]Xử lý chuỗi ký tự

  • Thread starter bvtvba
  • Ngày gửi
B

bvtvba

Guest
Được biết Smod @NhanSu là chuyên gia thực hành với các cách xử lý code nhanh gọn. Vậy topic này cho phép em được nhờ riêng anh.
Mong muốn xây dựng hàm:
function name: tuhocvba
Input : string
Output : string

Cụ thể:
Mã:
'INPUT: abc#x#y#z#saaaaa
'OUTPUT: abc#{xyzs}aaaaa

'INPUT: abc#xy#zb
'OUTPUT: abc#{x}y#{z}b
Một ký tự được coi là "xấu" nếu trước nó có dấu thăng #. Mong muốn nếu có các ký tự xấu liên tiếp đứng cạnh nhau thì nhóm lại. (ví dụ 1).
Ở ví dụ 2 là các ký tự "xấu" đứng rời rạc nhau.
Mong được học hỏi từ anh ạ.
 

NhanSu

SMod
Thành viên BQT
Mình đang bận làm việc nên sẽ làm cụ thể sau. Mình muốn hỏi thêm:
1. Trong chuỗi trên có trường hợp có nhiều dấu # liền nhau không?
2. Có dấu # ở cuối chuỗi input không?
3. Trong chuỗi ban đầu có dấu ngoặc nhọn không?
Nếu cả 3 câu trên là không thì có thể tìm lần lượt dấu #, thay thế "#a" thành "{a}", xóa tất cả "}{"đi.
Nếu câu 3 là có thì thay các dấu {} thành chuỗi gì đó rồi cuối cùng sửa lại.
 
B

bvtvba

Guest
1. Trong chuỗi trên không bao giờ có hai dấu ## đứng liền nhau.
2. KHông báo giờ có # ở vị trí cuối của string.
3.Chuỗi ban đầu có thể chứa dấu { }

Bài này làm cho vui, em với anh giao lưu, nên lúc nào rảnh anh làm nhé, nếu bận việc thì thôi.
 

NhanSu

SMod
Thành viên BQT
@bvtvba mình thử nhé,, làm theo hướng ở bài 2:
Mã:
Function TuHocVBA$(s$)
    Dim i&, c$
    s = Replace(s, "{", "MoNgoacNhon")
    s = Replace(s, "}", "DongNgoacNhon")
    s = Replace(s, "#MoNgoacNhon", "{MoNgoacNhon}")
    s = Replace(s, "#DongNgoacNhon", "{DongNgoacNhon}")
    
    i = 1
    Do
        i = InStr(i, s, "#")
        If i > 0 Then
            c = Mid(s, i + 1, 1)
            s = Replace(s, "#" & c, "{" & c & "}")
        Else
            s = Replace(s, "}{", "")
            s = Replace(s, "MoNgoacNhon", "{")
            TuHocVBA = Replace(s, "DongNgoacNhon", "}")
            Exit Function
        End If
    Loop
End Function
 
B

bvtvba

Guest
Cảm ơn bác nhưng bác sai rồi:
Mã:
'INPUT: abc#x#y#z#saaaaa
'OUTPUT: abc#{xyzs}aaaaa
Sub test()
    Dim s As String
    s = "abc#x#y#z#saaaaa"
    s = TuHocVBA(s)
    Debug.Print (s) 'abc{xyzs}aaaaa
End Sub
 

NhanSu

SMod
Thành viên BQT
Đúng rồi, mình làm thiếu dấu #, code sửa lại thành:
Mã:
Function TuHocVBA$(s$)
    Dim i&, c$
    s = Replace(s, "{", "MoNgoacNhon")
    s = Replace(s, "}", "DongNgoacNhon")
    s = Replace(s, "#MoNgoacNhon", "{MoNgoacNhon}")
    s = Replace(s, "#DongNgoacNhon", "{DongNgoacNhon}")
    
    i = 1
    Do
        i = InStr(i, s, "#")
        If i > 0 Then
            c = Mid(s, i + 1, 1)
            s = Replace(s, "#" & c, "{" & c & "}")
        Else
            s = Replace(s, "}{", "")
            s = Replace(s, "{", "#{")
            s = Replace(s, "MoNgoacNhon", "{")
            TuHocVBA = Replace(s, "DongNgoacNhon", "}")
            Exit Function
        End If
    Loop
End Function
 
B

bvtvba

Guest
Kết quả #6 đúng với nội dung test.
Em cho vào file tầm cỡ 1 triệu dòng thì không được.
Em nghĩ bác nên xử lý split(s,chr(10)) ra mảng thì hàm instr của bác mới hoạt động được.
 

NhanSu

SMod
Thành viên BQT
File 1m dòng là chuyện khác hẳn. Công thức chuẩn của Excel cũng bị đơ chứ nói gì đến udf. Trường hợp này có lẽ đơn giản nhất là dùng sub, nếu vẫn quá chậm thì cần dùng cách khác. Mình vẫn chưa hiểu split chuỗi làm gì?
 
B

bvtvba

Guest
Mình vẫn chưa hiểu split chuỗi làm gì?
Giá trị trả về của hàm này chắc chắn không thể lên tới 3 triệu : InStr(i, s, "#")
Nhưng nếu xử lý như này:
InStr(i, Cstr(arr(j)), "#") trong đó arr(j) là chuỗi ký tự dòng j của s thì được.
 

NhanSu

SMod
Thành viên BQT
Nếu chuỗi không có ký tự xuống dòng nào thì vẫn không được. Bạn cho mình file mẫu, hôm sau mình thử xem.
 
B

bvtvba

Guest
Văn bản như thế nào mà lại không có dấu xuống dòng bác. Em xử lý được rồi. Cám ơn bác.
 

tuhocvba

Administrator
Thành viên BQT
Lần sau cần hỏi gì em cứ đưa lên diễn đàn thôi.
Smod còn bao nhiêu việc, cũng không rảnh đâu.
 
Top