วิธีใช้นิพจน์ทั่วไป (Regex) ใน Microsoft Excel ทั้งในเซลล์และลูป


592

ฉันจะใช้นิพจน์ปกติใน Excel และใช้ประโยชน์จากการตั้งค่ากริดที่มีประสิทธิภาพเช่นเดียวกับ Excel สำหรับการจัดการข้อมูลได้อย่างไร

  • ฟังก์ชันในเซลล์เพื่อส่งคืนรูปแบบที่ตรงกันหรือค่าที่ถูกแทนที่ในสตริง
  • ย่อยไปยังลูปผ่านคอลัมน์ข้อมูลและแยกข้อมูลตรงกับเซลล์ที่อยู่ติดกัน
  • จำเป็นต้องตั้งค่าอะไรบ้าง
  • อักขระพิเศษของ Excel สำหรับนิพจน์ทั่วไปคืออะไร

ผมเข้าใจ Regex ไม่เหมาะสำหรับสถานการณ์ที่หลายคน ( ที่จะใช้หรือไม่ใช้การแสดงออกปกติ? ) ตั้งแต่ Excel สามารถใช้Left, Mid, Right, Instrคำสั่งชนิดสำหรับกิจวัตรที่คล้ายกัน


11
ฉันขอแนะนำVB / VBA Regexp บทความนี้โดย Patrick Matthews
brettdj

1
ลอง Add-in นี้ฟรี: seotoolsforexcel.com/regexpfind
Niels Bosma

1
อย่าลืมLike ผู้ประกอบการซึ่งให้ฟังก์ชั่นสไตล์ regex แบบเบา ๆ โดยทั่วไปแล้วจะเร็วกว่า regex มากแม้ว่าจะรวมอยู่ในกระบวนการย่อยหรือฟังก์ชัน
Egalth

คำตอบ:


955

นิพจน์ทั่วไปใช้สำหรับการจับคู่รูปแบบ

วิธีใช้ใน Excel ทำตามขั้นตอนเหล่านี้:

ขั้นตอนที่ 1 : เพิ่มการอ้างอิง VBA ใน "Microsoft VBScript Regular Expressions 5.5"

  • เลือกแท็บ "นักพัฒนา" ( ฉันไม่มีแท็บนี้ฉันจะทำอย่างไร )
  • เลือกไอคอน "Visual Basic" จากส่วน 'Code'
  • ในหน้าต่าง "Microsoft Visual Basic สำหรับแอปพลิเคชัน" เลือก "เครื่องมือ" จากเมนูด้านบน
  • เลือก "การอ้างอิง"
  • ทำเครื่องหมายที่ช่องถัดจาก "Microsoft VBScript Regular Expressions 5.5" เพื่อรวมไว้ในสมุดงานของคุณ
  • คลิก "ตกลง"

ขั้นตอนที่ 2 : กำหนดรูปแบบของคุณ

คำจำกัดความพื้นฐาน:

- พิสัย.

  • เช่นa-zจับคู่ตัวอักษรพิมพ์เล็กจาก a ถึง z
  • เช่น0-5จับคู่หมายเลขใด ๆ จาก 0 ถึง 5

[] จับคู่หนึ่งในวัตถุภายในวงเล็บเหล่านี้

  • เช่น[a]ตรงกับตัวอักษร
  • เช่น[abc]จับคู่อักษรเดี่ยวซึ่งอาจเป็น a, b หรือ c
  • เช่น[a-z]จับคู่อักษรตัวพิมพ์เล็กใด ๆ ของตัวอักษร

()จับคู่กลุ่มที่แตกต่างกันเพื่อวัตถุประสงค์ในการคืนสินค้า ดูตัวอย่างด้านล่าง

{} ตัวคูณสำหรับสำเนาซ้ำของรูปแบบที่กำหนดไว้ก่อนหน้า

  • เช่น[a]{2}จับคู่อักษรตัวพิมพ์เล็กสองตัวติดต่อกัน a:aa
  • เช่น[a]{1,3}ตรงกับอย่างน้อยหนึ่งถึงสามล่างตัวอักษรกรณีa, aa,aaa

+ จับคู่รูปแบบที่กำหนดไว้ก่อนหน้าอย่างน้อยหนึ่งรูปแบบขึ้นไป

  • เช่นa+จะตรงกับการติดต่อกันของa, aa, aaaและอื่น ๆ

? จับคู่ศูนย์หรือหนึ่งในรูปแบบที่กำหนดไว้ก่อนหน้า

  • เช่นรูปแบบอาจมีหรือไม่มีอยู่ แต่สามารถจับคู่ได้เพียงครั้งเดียวเท่านั้น
  • เช่น[a-z]?จับคู่สตริงว่างหรืออักษรตัวพิมพ์เล็กใด ๆ

* จับคู่รูปแบบที่กำหนดไว้ก่อนหน้าศูนย์หรือมากกว่านั้น - เช่นสัญลักษณ์แทนสำหรับรูปแบบที่อาจมีหรือไม่มีอยู่ - เช่น[a-z]*จับคู่สตริงว่างหรือสตริงตัวอักษรตัวพิมพ์เล็ก

. ตรงกับตัวละครใด ๆ ยกเว้นการขึ้นบรรทัดใหม่ \n

  • เช่นa.จับคู่สตริงอักขระสองตัวที่ขึ้นต้นด้วย a และลงท้ายด้วยอะไรก็ได้ยกเว้น\n

| หรือผู้ประกอบการ

  • เช่นa|bหมายถึงอย่างใดอย่างหนึ่งaหรือbสามารถจับคู่
  • เช่นred|white|orangeตรงกับหนึ่งในสีทั้งหมด

^ ไม่ใช่ผู้ประกอบการ

  • [^0-9]อักขระเช่นต้องไม่มีตัวเลข
  • เช่น[^aA]ตัวอักษรต้องไม่เป็นตัวพิมพ์เล็กaหรือตัวพิมพ์ใหญ่A

\ หนีอักขระพิเศษที่ตามมา (แทนที่เหนือพฤติกรรม)

  • เช่น\., \\, \(, \?, \$,\^

รูปแบบการยึด:

^ การจับคู่จะต้องเกิดขึ้นที่จุดเริ่มต้นของสตริง

  • เช่น^aตัวอักษรตัวแรกต้องเป็นตัวอักษรพิมพ์เล็กa
  • เช่น^[0-9]อักขระตัวแรกต้องเป็นตัวเลข

$ การจับคู่จะต้องเกิดขึ้นที่ส่วนท้ายของสตริง

  • เช่นa$ตัวอักษรตัวสุดท้ายจะต้องเป็นตัวอักษรพิมพ์เล็กa

ตารางที่สำคัญกว่า:

Order  Name                Representation
1      Parentheses         ( )
2      Multipliers         ? + * {m,n} {m, n}?
3      Sequence & Anchors  abc ^ $
4      Alternation         |

ตัวย่อที่กำหนดไว้ล่วงหน้า:

abr    same as       meaning
\d     [0-9]         Any single digit
\D     [^0-9]        Any single character that's not a digit
\w     [a-zA-Z0-9_]  Any word character
\W     [^a-zA-Z0-9_] Any non-word character
\s     [ \r\t\n\f]   Any space character
\S     [^ \r\t\n\f]  Any non-space character
\n     [\n]          New line

ตัวอย่างที่ 1 : เรียกใช้เป็นมาโคร

ตัวอย่างแมโครต่อไปนี้จะดูค่าในเซลล์A1เพื่อดูว่าอักขระ 1 หรือ 2 ตัวแรกเป็นตัวเลขหรือไม่ ถ้าเป็นเช่นนั้นจะถูกลบออกและส่วนที่เหลือของสตริงจะปรากฏขึ้น ถ้าไม่เช่นนั้นจะมีกล่องปรากฏขึ้นเพื่อบอกคุณว่าไม่พบข้อมูลที่ตรงกัน A1ค่าเซลล์ของ12abcจะคืนabcค่าของ1abcจะกลับมาabcมูลค่าของabc123จะกลับมา "ไม่ตรงกัน" เพราะตัวเลขไม่ได้อยู่ที่จุดเริ่มต้นของสตริง

Private Sub simpleRegex()
    Dim strPattern As String: strPattern = "^[0-9]{1,2}"
    Dim strReplace As String: strReplace = ""
    Dim regEx As New RegExp
    Dim strInput As String
    Dim Myrange As Range

    Set Myrange = ActiveSheet.Range("A1")

    If strPattern <> "" Then
        strInput = Myrange.Value

        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = strPattern
        End With

        If regEx.Test(strInput) Then
            MsgBox (regEx.Replace(strInput, strReplace))
        Else
            MsgBox ("Not matched")
        End If
    End If
End Sub

ตัวอย่างที่ 2 : เรียกใช้เป็นฟังก์ชันในเซลล์

ตัวอย่างนี้เหมือนกับตัวอย่างที่ 1 แต่เป็นการตั้งค่าให้เรียกใช้เป็นฟังก์ชันในเซลล์ วิธีใช้ให้เปลี่ยนรหัสเป็น:

Function simpleCellRegex(Myrange As Range) As String
    Dim regEx As New RegExp
    Dim strPattern As String
    Dim strInput As String
    Dim strReplace As String
    Dim strOutput As String


    strPattern = "^[0-9]{1,3}"

    If strPattern <> "" Then
        strInput = Myrange.Value
        strReplace = ""

        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = strPattern
        End With

        If regEx.test(strInput) Then
            simpleCellRegex = regEx.Replace(strInput, strReplace)
        Else
            simpleCellRegex = "Not matched"
        End If
    End If
End Function

วางสายของคุณ ( "12abc") A1ในเซลล์ ป้อนสูตรนี้=simpleCellRegex(A1)ในเซลล์B1และผลลัพธ์จะเป็น "abc"

ภาพผลลัพธ์


ตัวอย่างที่ 3 : วนรอบช่วง

ตัวอย่างนี้เหมือนกับตัวอย่างที่ 1 แต่วนลูปผ่านช่วงของเซลล์

Private Sub simpleRegex()
    Dim strPattern As String: strPattern = "^[0-9]{1,2}"
    Dim strReplace As String: strReplace = ""
    Dim regEx As New RegExp
    Dim strInput As String
    Dim Myrange As Range

    Set Myrange = ActiveSheet.Range("A1:A5")

    For Each cell In Myrange
        If strPattern <> "" Then
            strInput = cell.Value

            With regEx
                .Global = True
                .MultiLine = True
                .IgnoreCase = False
                .Pattern = strPattern
            End With

            If regEx.Test(strInput) Then
                MsgBox (regEx.Replace(strInput, strReplace))
            Else
                MsgBox ("Not matched")
            End If
        End If
    Next
End Sub

ตัวอย่างที่ 4 : แยกรูปแบบที่แตกต่าง

ตัวอย่างนี้วนลูปผ่านช่วง ( A1, A2& & A3) และค้นหาสตริงที่ขึ้นต้นด้วยตัวเลขสามหลักตามด้วยอักขระอัลฟ่าหนึ่งตัวและตามด้วยตัวเลข 4 หลัก ()แยกเอาท์พุทออกจากกันตรงรูปแบบการเข้าสู่เซลล์ที่อยู่ติดกันโดยใช้ หมายถึงรูปแบบครั้งแรกที่จับคู่ภายในชุดแรกของ$1()

Private Sub splitUpRegexPattern()
    Dim regEx As New RegExp
    Dim strPattern As String
    Dim strInput As String
    Dim Myrange As Range

    Set Myrange = ActiveSheet.Range("A1:A3")

    For Each C In Myrange
        strPattern = "(^[0-9]{3})([a-zA-Z])([0-9]{4})"

        If strPattern <> "" Then
            strInput = C.Value

            With regEx
                .Global = True
                .MultiLine = True
                .IgnoreCase = False
                .Pattern = strPattern
            End With

            If regEx.test(strInput) Then
                C.Offset(0, 1) = regEx.Replace(strInput, "$1")
                C.Offset(0, 2) = regEx.Replace(strInput, "$2")
                C.Offset(0, 3) = regEx.Replace(strInput, "$3")
            Else
                C.Offset(0, 1) = "(Not matched)"
            End If
        End If
    Next
End Sub

ผล:

ภาพผลลัพธ์


ตัวอย่างรูปแบบเพิ่มเติม

String   Regex Pattern                  Explanation
a1aaa    [a-zA-Z][0-9][a-zA-Z]{3}       Single alpha, single digit, three alpha characters
a1aaa    [a-zA-Z]?[0-9][a-zA-Z]{3}      May or may not have preceding alpha character
a1aaa    [a-zA-Z][0-9][a-zA-Z]{0,3}     Single alpha, single digit, 0 to 3 alpha characters
a1aaa    [a-zA-Z][0-9][a-zA-Z]*         Single alpha, single digit, followed by any number of alpha characters

</i8>    \<\/[a-zA-Z][0-9]\>            Exact non-word character except any single alpha followed by any single digit

22
Set regEx = Nothingคุณไม่ควรลืมที่จะ คุณจะได้รับข้อยกเว้นหน่วยความจำไม่เพียงพอเมื่อ Sub นั้นดำเนินการบ่อยครั้งเพียงพอ
Kiril

1
ฉันปรับตัวอย่างที่ 4 ด้วยSubMatchesเพื่อรักษา regex ที่ซับซ้อนมากขึ้นโดยทั่วไปฉันไม่ได้ใช้การแทนที่เมื่อทำการแยกหากใครสนใจ: stackoverflow.com/questions/30218413/…
Armfoot

11
สายเข้าเล่ม:Set regEx = CreateObject("VBScript.RegExp")
ZygD

2
ThisWorkbookเอาล่ะผมค่อนข้างมั่นใจว่ามันเป็นเพราะรหัสที่อยู่ใน ลองย้ายรหัสไปที่Moduleอื่น
พอร์ตแลนด์รันเนอร์

3
@PortlandRunner ใน "project explorer" (?) ไฟล์ excel นี้ไม่มีโฟลเดอร์ย่อย "Modules" แม้ว่าจะมีอีกไฟล์หนึ่งแสดงอยู่ คลิกขวาที่ไฟล์และเลือก 'ใส่โมดูล' จากนั้นดับเบิลคลิกที่ "โมดูล 1" และวางรหัส ที่บันทึกไว้ กลับไปที่สมุดงานและใส่รหัสในฟังก์ชันอีกครั้ง - ใช้งานได้ อาจจะเป็นคำตอบที่น่าสังเกตเพราะเห็นแก่ผู้ที่ไม่มีประสบการณ์เช่นฉัน? ขอบคุณสำหรับความช่วยเหลือ
youcantryreachingme

205

ในการใช้ประโยชน์จากนิพจน์ทั่วไปโดยตรงในสูตร Excel UDF (ฟังก์ชันที่ผู้ใช้กำหนดเอง) ต่อไปนี้สามารถช่วยได้ มันมากหรือน้อยโดยตรงโดยตรงฟังก์ชั่นการแสดงออกในฐานะที่เป็นฟังก์ชั่น excel

มันทำงานอย่างไร

ใช้เวลา 2-3 พารามิเตอร์

  1. ข้อความที่จะใช้ในการแสดงออกปกติบน
  2. การแสดงออกปกติ
  3. สตริงรูปแบบที่ระบุว่าควรดูผลลัพธ์อย่างไร มันสามารถมี$0, $1, $2และอื่น ๆ $0คือการแข่งขันทั้งหมด$1และขึ้นตรงกับกลุ่มการแข่งขันที่เกี่ยวข้องในการแสดงออกปกติ เริ่ม$0ต้นที่

ตัวอย่างบางส่วน

แยกที่อยู่อีเมล:

=regex("Peter Gordon: some@email.com, 47", "\w+@\w+\.\w+")
=regex("Peter Gordon: some@email.com, 47", "\w+@\w+\.\w+", "$0")

ผลลัพธ์ใน: some@email.com

แยกสารตั้งต้นหลายอย่าง:

=regex("Peter Gordon: some@email.com, 47", "^(.+): (.+), (\d+)$", "E-Mail: $2, Name: $1")

ผลลัพธ์ใน: E-Mail: some@email.com, Name: Peter Gordon

ในการแยกสตริงที่รวมกันในเซลล์เดียวออกเป็นส่วนประกอบในเซลล์หลายเซลล์:

=regex("Peter Gordon: some@email.com, 47", "^(.+): (.+), (\d+)$", "$" & 1)
=regex("Peter Gordon: some@email.com, 47", "^(.+): (.+), (\d+)$", "$" & 2)

ผลลัพธ์ใน: Peter Gordon some@email.com...

วิธีใช้

ในการใช้ UDF นี้ให้ทำดังต่อไปนี้ (อ้างอิงจากหน้า Microsoft นี้พวกเขามีข้อมูลเพิ่มเติมที่ดีอยู่ที่นั่น!):

  1. ใน Excel ในไฟล์ที่เปิดใช้งานแมโคร ('.xlsm') ให้กดALT+F11เพื่อเปิดMicrosoft Visual Basic สำหรับตัวแก้ไขแอปพลิเคชัน
  2. เพิ่มการอ้างอิง VBA ไปที่ไลบรารี่นิพจน์ปกติ (คัดลอกมาจากคำตอบ Portland Runners ++ ):
    1. คลิกที่เครื่องมือ -> การอ้างอิง (โปรดยกภาพหน้าจอภาษาเยอรมัน) เครื่องมือ -> การอ้างอิง
    2. ค้นหาMicrosoft VBScript Regular Expression 5.5ในรายการและทำเครื่องหมายที่ช่องถัดจาก
    3. คลิกตกลง
  3. คลิกที่แทรกโมดูล ถ้าคุณให้โมดูลของคุณชื่อที่แตกต่างกันทำให้แน่ใจว่าโมดูลไม่ได้มีชื่อเดียวกับ UDF ด้านล่าง (เช่นการตั้งชื่อโมดูลRegexและฟังก์ชั่นregexที่ทำให้เกิด# NAME!ข้อผิดพลาด)

    ไอคอนที่สองในแถวไอคอน -> โมดูล

  4. ในหน้าต่างข้อความขนาดใหญ่ที่อยู่ตรงกลางแทรกสิ่งต่อไปนี้:

    Function regex(strInput As String, matchPattern As String, Optional ByVal outputPattern As String = "$0") As Variant
        Dim inputRegexObj As New VBScript_RegExp_55.RegExp, outputRegexObj As New VBScript_RegExp_55.RegExp, outReplaceRegexObj As New VBScript_RegExp_55.RegExp
        Dim inputMatches As Object, replaceMatches As Object, replaceMatch As Object
        Dim replaceNumber As Integer
    
        With inputRegexObj
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = matchPattern
        End With
        With outputRegexObj
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = "\$(\d+)"
        End With
        With outReplaceRegexObj
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
        End With
    
        Set inputMatches = inputRegexObj.Execute(strInput)
        If inputMatches.Count = 0 Then
            regex = False
        Else
            Set replaceMatches = outputRegexObj.Execute(outputPattern)
            For Each replaceMatch In replaceMatches
                replaceNumber = replaceMatch.SubMatches(0)
                outReplaceRegexObj.Pattern = "\$" & replaceNumber
    
                If replaceNumber = 0 Then
                    outputPattern = outReplaceRegexObj.Replace(outputPattern, inputMatches(0).Value)
                Else
                    If replaceNumber > inputMatches(0).SubMatches.Count Then
                        'regex = "A to high $ tag found. Largest allowed is $" & inputMatches(0).SubMatches.Count & "."
                        regex = CVErr(xlErrValue)
                        Exit Function
                    Else
                        outputPattern = outReplaceRegexObj.Replace(outputPattern, inputMatches(0).SubMatches(replaceNumber - 1))
                    End If
                End If
            Next
            regex = outputPattern
        End If
    End Function
  5. บันทึกและปิดหน้าต่างMicrosoft Visual Basic สำหรับตัวแก้ไขแอปพลิเคชัน


6
คำตอบนี้รวมกับขั้นตอนที่นี่เพื่อสร้าง Add-In มีประโยชน์มาก ขอบคุณ. ตรวจสอบให้แน่ใจว่าคุณไม่ได้ให้โมดูลและใช้ชื่อเดียวกัน!
Chris Hunt

2
เพียงแค่ย้ำความคิดเห็นข้างต้นจาก Chris Hunt อย่าเรียกโมดูลของคุณว่า 'Regex' เช่นกัน คิดว่าฉันจะโมโหสักพักเนื่องจากฟังก์ชั่นใช้งานไม่ได้เนื่องจากข้อผิดพลาด #NAME
Chris

ฉันไปถั่วแล้วเมื่อฉันลองทุกอย่าง (รวมถึงการเปลี่ยนโมดูล / ชื่อ) และยังได้รับข้อผิดพลาด #NAME> _> i.imgur.com/UUQ6eCi.png
Enissay

@Enissay: ลองสร้างFunction foo() As Variant \n foo="Hello World" \n End FunctionUDF ขั้นต่ำเพื่อดูว่าใช้งานได้หรือไม่ ถ้าใช่ทำงานไปจนถึงสิ่งที่สมบูรณ์ข้างต้นหากไม่มีสิ่งพื้นฐานเสียหาย (แมโครถูกปิดใช้งานหรือไม่)
Patrick Böker

1
@Vijay: เดียวกันที่github.com/malcolmp/excel-regular-expressions
Vadim

64

ขยายคำตอบของpatszimสำหรับผู้ที่รีบร้อน

  1. เปิดสมุดงาน Excel
  2. Alt+ F11เพื่อเปิดหน้าต่าง VBA / Macros
  3. เพิ่มการอ้างอิงถึง regex ภายใต้เครื่องมือจากนั้นอ้างอิง
    ! [Excel VBA Form เพิ่มการอ้างอิง
  4. และเลือกMicrosoft VBScript Regular Expression 5.5
    ! [Excel VBA เพิ่มการอ้างอิง regex
  5. แทรกโมดูลใหม่ (รหัสต้องอยู่ในโมดูลมิฉะนั้นจะไม่ทำงาน)
    ! [Excel VBA ใส่รหัสโมดูล
  6. ในโมดูลที่ใส่ใหม่
    ! [Excel VBA แทรกรหัสลงในโมดูล
  7. เพิ่มรหัสต่อไปนี้:

    Function RegxFunc(strInput As String, regexPattern As String) As String
        Dim regEx As New RegExp
        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .pattern = regexPattern
        End With
    
        If regEx.Test(strInput) Then
            Set matches = regEx.Execute(strInput)
            RegxFunc = matches(0).Value
        Else
            RegxFunc = "not matched"
        End If
    End Function
  8. รูปแบบ regex ถูกวางไว้ในหนึ่งในเซลล์และใช้การอ้างอิงแบบสัมบูรณ์ในนั้น ! [ฟังก์ชัน Excel regex ใช้งานในเซลล์ ฟังก์ชั่นจะเชื่อมโยงกับเวิร์กบุ๊กที่สร้างขึ้น
    หากจำเป็นต้องใช้ในเวิร์กบุคอื่นให้จัดเก็บฟังก์ชันในPersonal.XLSB


1
ขอบคุณที่พูดถึงว่าจำเป็นต้องอยู่ใน Personal.xlsb เพื่อให้สามารถใช้ได้ในเอกสาร Excel ทั้งหมดที่คุณใช้งาน คำตอบอื่น ๆ ส่วนใหญ่ไม่ชัดเจน Personal.XLSB จะเข้าไปในโฟลเดอร์ (อาจจำเป็นต้องสร้างโฟลเดอร์) C: \ Users \ ชื่อผู้ใช้ \ AppData \ Local \ Microsoft \ Excel \ XLStart โฟลเดอร์
Mark Stewart

26

นี่คือความพยายามของฉัน:

Function RegParse(ByVal pattern As String, ByVal html As String)
    Dim regex   As RegExp
    Set regex = New RegExp

    With regex
        .IgnoreCase = True  'ignoring cases while regex engine performs the search.
        .pattern = pattern  'declaring regex pattern.
        .Global = False     'restricting regex to find only first match.

        If .Test(html) Then         'Testing if the pattern matches or not
            mStr = .Execute(html)(0)        '.Execute(html)(0) will provide the String which matches with Regex
            RegParse = .Replace(mStr, "$1") '.Replace function will replace the String with whatever is in the first set of braces - $1.
        Else
            RegParse = "#N/A"
        End If

    End With
End Function

9

ฉันต้องการใช้สิ่งนี้เป็นฟังก์ชั่นเซลล์ (เช่นSUMหรือVLOOKUP) และพบว่ามันง่ายต่อการ:

  1. ตรวจสอบให้แน่ใจว่าคุณอยู่ในไฟล์ Excel ที่เปิดใช้งานแมโคร (บันทึกเป็น xlsm)
  2. เปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์Alt+F11
  3. เพิ่มMicrosoft VBScript Regular Expressions 5.5เช่นเดียวกับคำตอบอื่น ๆ
  4. สร้างฟังก์ชันต่อไปนี้ในสมุดงานหรือในโมดูลของตัวเอง:

    Function REGPLACE(myRange As Range, matchPattern As String, outputPattern As String) As Variant
        Dim regex As New VBScript_RegExp_55.RegExp
        Dim strInput As String
    
        strInput = myRange.Value
    
        With regex
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = matchPattern
        End With
    
        REGPLACE = regex.Replace(strInput, outputPattern)
    
    End Function
  5. จากนั้นคุณสามารถใช้ในเซลล์ด้วย=REGPLACE(B1, "(\w) (\d+)", "$1$2")(เช่น: "A 243" ถึง "A243")


การตั้งชื่อเอาท์พุทรูปแบบนี้ทำให้ฉันหลุด มันเป็นค่าทดแทน
Thor

1
ใช่. ฉันคิดว่าฉันทิ้งมันไว้ที่ชื่อ pattern ดังนั้นมันจึงไม่ใช่แค่การแทนที่สตริงและคุณสามารถใช้กลุ่มการจับคู่ regex เช่น $ 1 $ 2 เป็นต้น
DeezCashews

7

นี่ไม่ใช่คำตอบโดยตรง แต่อาจเป็นทางเลือกที่มีประสิทธิภาพมากขึ้นสำหรับการพิจารณาของคุณ ซึ่งเป็นสิ่งที่ Google ชีตมีฟังก์ชั่น Regexหลายฟังก์ชั่นซึ่งสามารถทำได้อย่างสะดวกและช่วยหลีกเลี่ยงกระบวนการทางเทคนิคบางอย่างใน Excel เห็นได้ชัดว่ามีข้อได้เปรียบบางอย่างในการใช้ Excel บนพีซีของคุณ แต่สำหรับผู้ใช้ส่วนใหญ่ Google ชีตจะมอบประสบการณ์ที่เหมือนกันและอาจมอบประโยชน์บางประการในการพกพาและการแบ่งปันเอกสาร

พวกเขาเสนอ

REGEXEXTRACT: แยกสตริงย่อยที่ตรงกันตามนิพจน์ทั่วไป

REGEXREPLACE: แทนที่ส่วนของสตริงข้อความด้วยสตริงข้อความอื่นโดยใช้นิพจน์ทั่วไป

SUBSTITUTE: แทนที่ข้อความที่มีอยู่ด้วยข้อความใหม่ในสตริง

แทนที่: แทนที่ส่วนของสตริงข้อความด้วยสตริงข้อความอื่น

คุณสามารถพิมพ์สิ่งเหล่านี้ลงในเซลล์โดยตรงได้และจะสร้างสิ่งที่คุณต้องการ

=REGEXMATCH(A2, "[0-9]+")

พวกเขายังทำงานได้ค่อนข้างดีเมื่อรวมกับฟังก์ชั่นอื่น ๆ เช่นคำสั่งIFเช่น:

=IF(REGEXMATCH(E8,"MiB"),REGEXEXTRACT(E8,"\d*\.\d*|\d*")/1000,IF(REGEXMATCH(E8,"GiB"),REGEXEXTRACT(E8,"\d*\.\d*|\d*"),"")

ป้อนคำอธิบายรูปภาพที่นี่

หวังว่านี่จะช่วยให้การแก้ปัญหาง่าย ๆ สำหรับผู้ใช้ที่รู้สึกยั่วยุโดยองค์ประกอบ VBS ของ Excel


ขอบคุณสำหรับการแบ่งปันอเล็กซ์ สิ่งนี้มีประโยชน์สำหรับผู้ที่มองหาเวอร์ชั่นของ Google คุณอาจลองเขียนและตอบคำถามอื่นที่เฉพาะเจาะจงกับ Google ชีต Regex เนื่องจากมีระบบการตั้งชื่อเป็นของตัวเองและจะเป็นประโยชน์อย่างมากต่อผู้อื่น ไม่ว่าคุณมี upvote ของฉัน!
นักวิ่งพอร์ตแลนด์

4

นี่คือ regex_subst()ฟังก์ชั่น ตัวอย่าง:

=regex_subst("watermellon", "[aeiou]", "")
---> wtrmlln
=regex_subst("watermellon", "[^aeiou]", "")
---> aeeo

นี่คือรหัสที่เรียบง่าย (ง่ายกว่าสำหรับฉัน) ฉันไม่สามารถหาวิธีสร้างรูปแบบผลลัพธ์ที่เหมาะสมโดยใช้ด้านบนเพื่อทำงานเหมือนตัวอย่างของฉัน:

Function regex_subst( _
     strInput As String _
   , matchPattern As String _
   , Optional ByVal replacePattern As String = "" _
) As Variant
    Dim inputRegexObj As New VBScript_RegExp_55.RegExp

    With inputRegexObj
        .Global = True
        .MultiLine = True
        .IgnoreCase = False
        .Pattern = matchPattern
    End With

    regex_subst = inputRegexObj.Replace(strInput, replacePattern)
End Function

1

ฉันไม่ต้องการเปิดใช้งานไลบรารีอ้างอิงเนื่องจากฉันต้องการให้สคริปต์ของฉันสามารถพกพาได้ Dim foo As New VBScript_RegExp_55.RegExpเส้นที่เกิดจากUser Defined Type Not Definedข้อผิดพลาด แต่ผมพบว่าวิธีการแก้ปัญหาที่ทำงานสำหรับฉัน

สิ่งที่คุณจะต้องการจะทำคือใส่สตริงตัวอย่างเช่นในเซลล์แล้วทดสอบของคุณA1 strPatternเมื่อทำงานแล้วปรับrngตามต้องการ

Public Sub RegExSearch()
'/programming/22542834/how-to-use-regular-expressions-regex-in-microsoft-excel-both-in-cell-and-loops
'https://wellsr.com/vba/2018/excel/vba-regex-regular-expressions-guide/
'https://www.vitoshacademy.com/vba-regex-in-excel/
    Dim regexp As Object
    'Dim regex As New VBScript_RegExp_55.regexp 'Caused "User Defined Type Not Defined" Error
    Dim rng As Range, rcell As Range
    Dim strInput As String, strPattern As String

    Set regexp = CreateObject("vbscript.regexp")
    Set rng = ActiveSheet.Range("A1:A1")

    strPattern = "([a-z]{2})([0-9]{8})"
    'Search for 2 Letters then 8 Digits Eg: XY12345678 = Matched

    With regexp
        .Global = False
        .MultiLine = False
        .ignoreCase = True
        .Pattern = strPattern
    End With

    For Each rcell In rng.Cells

        If strPattern <> "" Then
            strInput = rcell.Value

            If regexp.test(strInput) Then
                MsgBox rcell & " Matched in Cell " & rcell.Address
            Else
                MsgBox "No Matches!"
            End If
        End If
    Next
End Sub

ฉันไม่ต้องการที่จะเปิดใช้งานห้องสมุดอ้างอิงเพราะฉันต้องการให้สคริปต์ของฉันเป็นแบบพกพา - VBScript_RegExp_55ห้องสมุดนั้นค่อนข้างแพร่หลายดังนั้นจึงมีความเสี่ยงต่ำมากที่ไม่ได้อยู่ในเครื่องเป้าหมายที่เฉพาะเจาะจง และการเปลี่ยนจาก Early Bound เป็น Late Bound ไม่สามารถแก้ปัญหาการพกพาได้ (โค้ดจะยังคงมีข้อผิดพลาดเฉพาะตอนรันไทม์มากกว่าเวลาคอมไพล์)
chris neilsen

1
ไม่นั่นไม่เป็นความจริงเลยสคริปต์นี้สามารถแชร์กับผู้ใช้รายอื่นได้โดยไม่ต้องเปิดใช้งานสิ่งที่พกพาได้ ขอบคุณสรรพสินค้า
FreeSoftwareServers

1
แน่นอน แต่รหัส RegEx จะไม่สามารถใช้งานได้ หากสิ่งที่ RegEx เป็นส่วนหนึ่งของสมุดงานห้องสมุดที่มีขนาดใหญ่ขึ้นฉันคิดว่าการที่มันไม่ได้มีข้อผิดพลาดในการคอมไพล์ดังนั้นการอนุญาตให้ใช้ส่วนอื่น ๆ นั้นอาจมีประโยชน์
chris neilsen

1

เพื่อเพิ่มเนื้อหาที่มีค่าฉันต้องการสร้างการแจ้งเตือนนี้ว่าทำไมบางครั้ง RegEx ภายใน VBA จึงไม่เหมาะ ไม่ใช่ทุกสำนวนที่รองรับ แต่อาจโยนError 5017และอาจทำให้ผู้เขียนเดา (ซึ่งฉันเป็นเหยื่อของตัวเอง)

ในขณะที่เราสามารถหาบางแหล่งที่มาเกี่ยวกับสิ่งที่จะได้รับการสนับสนุนก็จะเป็นประโยชน์ที่จะทราบว่า metacharacters ฯลฯ จะไม่ได้รับการสนับสนุน อธิบายเพิ่มเติมในเชิงลึกที่สามารถพบได้ที่นี่ กล่าวถึงในแหล่งนี้:

"แม้ว่า" การแสดงออกปกติของ VBScript ... เวอร์ชัน 5.5 จะใช้คุณสมบัติ regex ที่จำเป็นบางประการที่ขาดหายไปใน VBScript รุ่นก่อนหน้า ... JavaScript และ VBScript ใช้นิพจน์ปกติสไตล์ Perl อย่างไรก็ตามพวกเขาขาดคุณสมบัติขั้นสูงจำนวนมากที่มีอยู่ใน Perl และรสชาติการแสดงออกปกติที่ทันสมัยอื่น ๆ : "


ดังนั้นไม่รองรับคือ:

  • เริ่มต้นของ String ancor \Aหรือใช้^เครื่องหมายรูปหมวกเพื่อจับคู่ postion ก่อนอักขระตัวแรกในสตริง
  • End of String ancor \Zหรือใช้$เครื่องหมายดอลลาร์เพื่อจับคู่ตำแหน่งหลังอักขระสุดท้ายในสตริง
  • บวก LookBehind เช่น: (?<=a)b(ขณะ Lookahead postive จะสนับสนุน)
  • LookBehind เชิงลบเช่น: (?<!a)b(ขณะ lookahead เชิงลบจะได้รับการสนับสนุน)
  • การจัดกลุ่มอะตอม
  • ครอบครอง Quantifiers
  • Unicode เช่น: \{uFFFF}
  • กลุ่มที่มีชื่อการจับ หรือใช้กลุ่มการจับภาพแบบตัวเลข
  • Inline modifiers เช่น: /i(case sensitive) หรือ/g(global) เป็นต้นตั้งค่าเหล่านี้ผ่านRegExpคุณสมบัติของวัตถุ> RegExp.Global = TrueและRegExp.IgnoreCase = Trueถ้ามี
  • เงื่อนไข
  • ปกติการแสดงออกความคิดเห็น เพิ่มเหล่านี้ด้วย'ความคิดเห็นปกติในสคริปต์

ฉันชนกำแพงมากกว่าหนึ่งครั้งโดยใช้นิพจน์ทั่วไปภายใน VBA มักจะมีLookBehindแต่บางครั้งฉันก็ลืมปรับเปลี่ยน ฉันไม่เคยมีฉากหลังทั้งหมดที่กล่าวมาข้างต้นมาก่อน แต่คิดว่าฉันจะพยายามพูดถึงข้อมูลเชิงลึกเพิ่มเติม รู้สึกอิสระที่จะแสดงความคิดเห็น / แก้ไข / เพิ่ม บิ๊กตะโกนออกไปที่express-expressions.info ปกติสำหรับข้อมูลมากมาย

PSคุณได้กล่าวถึงวิธีการและฟังก์ชั่น VBA เป็นประจำและฉันสามารถยืนยันได้ว่าอย่างน้อยพวกเขา (อย่างน้อยสำหรับตัวฉันเอง) ได้รับประโยชน์ในรูปแบบของตัวเองที่ RegEx จะล้มเหลว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.