精华内容
下载资源
问答
  • vba正则表达式判断日期
    2021-06-10 12:38:17

    1、什么是正则表达式

    正则表达式是一个天才创建的用于快速检索匹配字符串,通过简单的表达式匹配文本。

    2、正则表达式的组成

    正则表达式也是一个字符串,包括元字符、限定符和正常意义的字符。正则表达式强大的地方就在元字符和限定符。

    3、限定符

    很多人讲这个都是先讲元字符。其实先讲限定符更加容易吸收。限定符是表示前面字符或元字符出现的次数。主要限定符如下:限定符含义

    *表示前面字符或元字符出现0次或多次。例如:zo*m,可以匹配zm,zom,zoom

    +表示前面字符或元字符出现1次或多次。例如:zo+m,可以匹配zom,zoom

    ?表示前面字符或元字符出现0次或1次。例如:zo?m,可以匹配zm,zom

    {n}表示前面字符或元字符出现n次。例如:zo{3}m,可以匹配zooom

    {n,m}表示前面字符或元字符出现n到m次。例如:zo{1,3}m,可以匹配zom,zoom,zooom

    {n,}表示前面字符或元字符至少出现n次。例如:zo{2,}m,可以匹配zoom,zooom等等

    当然,限定符用法不止这些。正则表达式还有个规则叫贪婪与吝啬。有些人也叫贪婪与懒惰。这个“贪婪与吝啬”是正则表达式难点和重点之一。

    例如,字符串“n123n456n789n”。那么我们怎么匹配获取“n123n”和“n123n456n789n”呢。

    使用正则表达式,首先要找规律。很明显我们要获取的内容开头和结尾都有一个字母n,中间是数字或字母。我们先学一个元字符。元字符是可以代表一定含义或规律的字符。可以匹配除了换行符之外的任意字符是小数点。

    那么我们的表达式可以这么写:n.+n

    两个字母n,中间夹着1个或多个任意字符。

    但这样只能匹配得到一个结果:n123n456n789n。在我们没有对其任何限制的情况下,正则表达式会尽可能多匹配符合条件的结果。从头到尾整个都符合,所以都匹配了。这个称之为贪婪匹配。

    那如何做到尽可能少的匹配。这个就需要加个?进行限制。

    例如,表达式:n.+?n

    这个表达式尽可能少匹配,也就是说碰到一次符合条件的就立马返回结果。结果可以匹配到“n123n”、“n789n”。

    这种规则叫做吝啬匹配。只要在限定符后面再加个问号即可。

    4、元字符

    元字符是用于匹配字符串,可以代表一定含义或规律的字符串。主要的元字符如下:元字符含义

    .小数点,代表除了换行符以外的任意字符

    \转义,若我想匹配一些被正则表达式占用的字符,例如小数点,可以用\.

    [abc]匹配中括号内的字符,例如[a-zA-Z],可以匹配到大小写字母

    [^abc]不匹配中括号内的字符,例如[^a-z],表示不匹配小写字母

    \w可以匹配字母、下划线和数字,相当于[a-zA-Z0-9_]

    \W大写的W是小写的w相反情况,也就是不匹配字母、下划线和数字。相当于[^a-zA-Z0-9_]

    \s匹配任意空白符,相当于[\f\n\r\t\v]

    \S匹配任意非空符,相当于[^\f\n\r\t\v]或[^\s]

    \d匹配数字,相当于[0-9]

    \D匹配非数字,相当于[^0-9]

    \b匹配单词的边界。这个匹配英文单词特别有用。例如\b[\w']+?\b就可以匹配任意单词了

    \f匹配换页符

    \n匹配换行符

    \r匹配回车符

    \t匹配tab制表符

    \v匹配垂直制表符

    ^不在中括号内的^,表示从字符串的开头开始匹配

    $表示匹配到字符串的结尾

    x|y匹配x或y

    (表达式)元组,用小括号括起来的表达式当作一个元组,可以当作一个整体,也可以被\1\2\3这样类似索引获取。

    元字符比较多,这里就建议大家先收藏,需要用的时候再查阅。多用几次就自然记住了。

    这里还有个小技巧,若我想匹配全部任意字符,包括换行符。可以用一组相反的元字符,例如[\s\S],就可以匹配全部任意字符。

    5、常见的正则表达式

    说了这么多,晕了没?看一些实例:

    1)匹配邮编,邮编是6位数字。正则表达式:\d{6}

    2)匹配手机,手机号是11位数字。正则表达式:\d{11}

    3)匹配电话,电话是区号-号码组成,区号有3到4位,号码有6到9位。正则表达式:\d{3,4}-\d{6,9}

    4)匹配日期,日期格式如1992-5-30,明显数字加横线组成。正则表达式:\d{4}-\d{1,2}-\d{1,2}

    5)匹配汉字,汉字需要通过编码转义,汉字都unicode编码中都在一个范围内。正则表达式:[\u4e00-\u9fa5]

    6、vba中使用正则表达式

    若只是上面这些内容,那么还是纸上谈兵,需要应用到实际中。看看如何在vba中使用正则表达式。

    vba使用正则表达式需要用到一个RegExp对象。

    该对象可以通过引用Microsoft VBScript Regular Expressions 5.5。再声明定义:DimregAsNewRegExp

    还可以直接用CreateObject方法创建:DimregAsObject

    setreg=CreateObject("VBScript.Regexp")

    创建RegExp对象之后,看看它的相关属性和方法。

    属性:

    1)Global,是否全局匹配,若为False,匹配到一个结果之后,就不再匹配。默认False,建议设为True;

    2)IgnoreCase,是否忽略大小写,默认False,建议设为False,这个会影响到正常表达式匹配;

    3)Multiline,是否跨行匹配,默认False,建议设为False,这个会影响到正常表达式匹配;

    4)Pattern,获取或设置正则表达式。

    方法:

    1)Execute,执行匹配

    2)Replace,根据正确表达式全部替换

    3)Test,测试正则表达式能否匹配到内容

    举一些典型的例子:

    1)判断是否存在数字PublicFunctionCheckNumber(strAsString)AsBoolean

    DimregAsObject

    Setreg=CreateObject("VBScript.Regexp")

    Dimis_existAsBoolean

    Withreg

    .Global=True

    .Pattern="\d"

    is_exist=.Test(str)

    EndWith

    CheckNumber=is_exist

    EndFunction

    用Test方法,判断能否匹配到数字。

    2)获取所有编号PublicSubGetCode()

    DimregAsObject

    Setreg=CreateObject("VBScript.Regexp")

    DimstrAsString

    str="编号:ABC123155 日期:2016-01-11"&_

    "编号:ABD134215 日期:2016-02-21"&_

    "编号:CBC134216 日期:2016-01-15"

    reg.Global=Truereg.Pattern="[A-Z]{3}\d+"'获取匹配结果'

    DimmatchesAsObject,matchAsObject

    Setmatches=reg.Execute(str)

    '遍历所有匹配到的结果'

    ForEachmatchInmatches

    '测试输出到立即窗口'

    Debug.Printmatch

    Next

    EndSub

    因为这个编号是3个大写字母和多个数字组成。可以利用代码中的表达式匹配到3个结果:ABC123155、ABD134215和CBC134216。

    3)去掉字符串中的数字PublicFunctionClearNumber(strAsString)AsString

    DimregAsObject

    Setreg=CreateObject("VBScript.Regexp")

    reg.Global=True

    reg.Pattern="\d"

    '把所有数字替换成空'

    ClearNumber=reg.Replace(str,"")

    EndFunction

    执行ClearNumber函数,即可去掉数字。例如ClearNumber("你342好234啊"),可得到"你好啊"。

    4)获取子字符串

    例如想获取某些字符串中的部分数据,可以匹配完成之后,再用字符串函数处理。但其实不用,用元组可以一次性搞定。PublicSubGetHref()

    DimregAsObject

    Setreg=CreateObject("VBScript.Regexp")

    DimstrAsString

    reg.Global=True

    '获取a标签中href的属性值'

    reg.Pattern="href='(.+?)'"

    '获取匹配结果'

    DimmatchesAsObject,matchAsObject

    Setmatches=reg.Execute(str)

    '遍历所有匹配到的结果'

    ForEachmatchInmatches

    '测试输出子表达式到立即窗口'

    Debug.Printmatch.SubMatches(0)

    Next

    EndSub

    这里,可以通过match的SubMatches集合获取元组里面的内容。轻松得到xxx1和xxx2。

    7、其他说明

    vba的正则表达式不是很完整,没有递归的功能。递归是可以匹配公式或html代码等。有兴趣可以了解一下。

    更多相关内容
  • 第4行代码创建正则表达式对象。 第5行代码设置全局匹配。 第6行代码设置匹配模式。 第7行代码读取A1单元格的内容。 第9行代码判断是否匹配成功。 第10~12行代码循环处理匹配结果。 第11行代码输出匹配值。通过观察...

    实例需求:提取文字中的4位数字年份(19xx或者20xx),文字中包含其他的数字,例如多余4位的:0749345,非年份数字:H-1803F。

    在这里插入图片描述

    示例代码如下。

    Sub Demo()
        Dim regExp As Object
        Dim aRes, arr
        Set regExp = CreateObject("vbscript.regExp")
        regExp.Global = True
        regExp.Pattern = "\D((19|20)\d{2})\D"
        txt = [a1].Value
        Set objMatch = regExp.Execute(txt)
        If objMatch.Count > 0 Then
            For Each mat In objMatch
                Debug.Print mat.submatches(0)
            Next
        End If
        Set regExp = Nothing
    End Sub
    

    【代码解析】
    第4行代码创建正则表达式对象。
    第5行代码设置全局匹配。
    第6行代码设置匹配模式。
    第7行代码读取A1单元格的内容。
    第9行代码判断是否匹配成功。
    第10~12行代码循环处理匹配结果。
    第11行代码输出匹配值。

    正则表达式说明
    \D匹配一个非数字字符
    `(1920)\d{2}`
    \D年份数字之后匹配一个非数字字符

    通过观察发现年份字符有的在圆括号中,有的在方括号中,有的没有括号,因此不能使用此特征。无论是否有括号,年份前后都分别有一个非数字字符,这是本正则匹配的核心点。

    【立即窗口】中的输出结果如下所示。

    在这里插入图片描述

    展开全文
  • VBA 利用正则表达式筛选数据

    千次阅读 2020-08-27 21:43:56
    =path & sh.Name & ".csv" Next End Sub 三、利用正则表达式进行定向提取 正则表达式之前没有提到过,VBA启用的话现在请记得在VBE——工具——引用中添加 Microsoft VBScript Regular Expressions 5.5: 再认识一下...

    先讲讲其他的小栗子

    一、批量制作工资条表头

    以运行也没发现下面的代码什么问题,但就是慢得出奇,还有更好地方法还请小伙伴告知一下哟~

    Sub gz()
        '批量添加工资标题
        
        Application.ScreenUpdating = False
        Dim i As Integer
        Dim myRow As Integer
        Dim sh As Worksheet
    
        Set sh = Sheets(1)
        myRow = sh.Range("A1").End(xlDown).Row
        
        For i = myRow To 3 Step -1
            sh.Rows(i).Insert Shift:=xlDown, copyorigin:=xlformatleftorabove
            sh.Range("a1").Resize(1, 8).Copy sh.Range("A" & i)
        Next
        
        Application.ScreenUpdating = True
    End Sub

    二、批量将工作表拆分为单独文件

    这个很简单啦,以前也做过,再练习一下

    Sub div()
        Dim sh As Worksheet
        Dim path As String
        
        path = "E:\"
        For Each sh In ThisWorkbook.Worksheets
            sh.SaveAs Filename:=path & sh.Name & ".csv"
        Next
    End Sub

    三、利用正则表达式进行定向提取

    正则表达式之前没有提到过,VBA启用的话现在请记得在VBE——工具——引用中添加 Microsoft VBScript Regular Expressions 5.5:

    再认识一下VBA中正则的属性和方法

    属性

    说明

    方法

    说明

    Global

    Boolean值,指明单次匹配或者全部匹配

    Execute

    将正则模式应用于字符串,并返回Matchs集合

    IgnoreCase

    Boolean值,指明匹配模式是否大小写敏感

    Replace

    替换正则模式匹配的文本

    Pattern

    指定用于搜索的正则模式

    Test

    对字符串执行正则匹配,返回Boolean值说明匹配是否成功

    Multiline

    指定的搜索字符串分布在多行

      

     

    现在用一下试试,来个最简单的例子

    比如写了一堆废话,然后我只想要里面的邮箱,可以这样操作:

     

    Sub reg()
        Dim reg As New RegExp
        Dim mc As MatchCollection
        Dim myMail As String
    
        myMail = "我的邮箱是12345@qq.com,快加我为好友吧"  
        With reg
            .Global = True
            .IgnoreCase = False
            '邮箱的正则表达
            .Pattern = "\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
        End With
        Set mc = reg.Execute(myMail)
        MsgBox mc(0)       
    End Sub

    如果一个内容里面涉及到多个符合条件的值,且都需要输出的话,需要加match参数用来遍历MatchCollection

    Sub reg()
        Dim reg As New RegExp
        Dim m As Match
        Dim mc As MatchCollection
        Dim myMail As String
        Dim msg As String
        myMail = "我的QQ1:12345@qq.com,QQ2:1111@qq.com,QQ3:123@qq.com"
        With reg
            .Global = True
            .IgnoreCase = False
            '邮箱的正则表达
            .Pattern = "\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
        End With
    
        Set mc = reg.Execute(myMail)
        
        For Each m In mc
            msg = msg & m.Value & vbNewLine
        Next
        MsgBox msg
    End Sub



    一些常用的正则表达式如下(出处:https://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html(作者:zxin.cnblogs.com)为了防止失效,拷贝了一份过来:

    一、校验数字的表达式

     1 数字:^[0-9]*$
     2 n位的数字:^\d{n}$
     3 至少n位的数字:^\d{n,}$
     4 m-n位的数字:^\d{m,n}$
     5 零和非零开头的数字:^(0|[1-9][0-9]*)$
     6 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
     7 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
     8 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
     9 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
    10 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
    11 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
    12 非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
    13 非负整数:^\d+$ 或 ^[1-9]\d*|0$
    14 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
    15 非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
    16 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
    17 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
    18 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
    19 浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

    二、校验字符的表达式

     1 汉字:^[\u4e00-\u9fa5]{0,}$
     2 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
     3 长度为3-20的所有字符:^.{3,20}$
     4 由26个英文字母组成的字符串:^[A-Za-z]+$
     5 由26个大写英文字母组成的字符串:^[A-Z]+$
     6 由26个小写英文字母组成的字符串:^[a-z]+$
     7 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
     8 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
     9 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
    10 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
    11 可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
    12 禁止输入含有~的字符:[^~\x22]+

    三、特殊需求表达式

     1 Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
     2 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
     3 InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
     4 手机号码:^(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])\d{8}$ (由于工信部放号段不定时,所以建议使用泛解析 ^([1][3,4,5,6,7,8,9])\d{9}$)
     5 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$ 
     6 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7} 
     7 18位身份证号码(数字、字母x结尾):^((\d{18})|([0-9x]{18})|([0-9X]{18}))$
     8 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
     9 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
    10 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$  
    11 日期格式:^\d{4}-\d{1,2}-\d{1,2}
    12 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
    13 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$ 
    14 钱的输入格式:
    14.1 有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$ 
    14.2 这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$ 
    14.3 一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$ 
    14.4 这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$ 
    14.5 必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$ 
    14.6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$ 
    14.7 这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$ 
    14.8 1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$ 
    15 xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
    16 中文字符的正则表达式:[\u4e00-\u9fa5]
    17 双字节字符:[^\x00-\xff]    (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
    18 空白行的正则表达式:\n\s*\r    (可以用来删除空白行)
    19 HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />    (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
    20 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$)    (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
    21 腾讯QQ号:[1-9][0-9]{4,}    (腾讯QQ号从10000开始)
    22 中国邮政编码:[1-9]\d{5}(?!\d)    (中国邮政编码为6位数字)
    23 IP地址:\d+\.\d+\.\d+\.\d+    (提取IP地址时有用)
    24 IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)) 

     

    展开全文
  • 这个需要也并不复杂,用VBA代码逐个判断字符和其前后的字符集可以区分每组,高手可以写出递归调用过程。我们还是来看一下正则如何处理这种问题。 Sub RegExpDemo() Dim strTxt As String Dim objRegEx As Object, ...

    实例需求:数据保存在A列中,需要将其中重复字符分拆后保存在后续的列中,为简化示例代码,只考虑小写英文字符。

    这个需求也并不复杂,用VBA代码逐个判断字符和其前后的字符对比,就可以区分每组,高手可以写出递归调用过程。用正则处理这种问题会更简单。

    Sub RegExpDemo()
        Dim strTxt As String
        Dim objRegEx As Object, objMatch As Object
        Dim objMH As Object, c As Range
        Set objRegEx = CreateObject("vbscript.regexp")
        objRegEx.Global = True
        objRegEx.Pattern = "([a-z])\1*"
        Range("B:AA").ClearContents
        For Each c In Range([A1], Cells(Rows.Count, "A").End(xlUp))
            strTxt = c.Value
            Set objMatch = objRegEx.Execute(strTxt)
            If objMatch.Count > 0 Then
                col = 2
                For Each objMH In objMatch
                    Cells(c.Row, col) = objMH.Value
                    col = col + 1
                Next
            End If
        Next
        Set objMH = Nothing
        Set objMatch = Nothing
        Set objRegEx = Nothing
    End Sub
    
    

    【代码解析】
    第5行代码使用后期绑定创建正则对象。
    第6行代码设置为全局搜索模式。
    第7行代码指定正则匹配字符串,([a-z])用于匹配单个小写英文字符,并提取为第一组,\1*含义是第一组字符重复0次(也就是只有单个字符的情况)或者多次。
    第8和代码清空后续列用于保存结果。
    第9行代码第19行代码循环处理工作表中的数据。
    第11行执行正则匹配。
    如果匹配成功,第14行到第17行代码将匹配结果写入工作表后续列中。
    注意第15行代码读取的是objMH.Value,而不是objMH.submatches(0).Value。


    似乎这个代码也没有什么神奇的地方,只是匹配模式中使用了匹配组\1

    接下来才是今天要讲的重点,上面的正则匹配是通用思路,解决问题时,都是去设法提取匹配的字符串,然后在VBA中加工,这个示例需要写入工作表单元格,那么只要拆分成数组,就可以一次性写入单元格区域了,VBA中拆分数组肯定是用Split函数了。下面的升级版解决方案中用到了正则替换。

    Sub RegExpRepDemo()
        Dim strTxt As String, arrRes
        Dim objRegEx As Object, objMatch As Object
        Dim objMH As Object, c As Range
        Set objRegEx = CreateObject("vbscript.regexp")
        objRegEx.Global = True
        objRegEx.Pattern = "([a-z])(?!\1|$)"
        Range("B:AA").ClearContents
        For Each c In Range([A1], Cells(Rows.Count, "A").End(xlUp))
            strTxt = c.Value
            arrRes = Split(objRegEx.Replace(strTxt, "$1 "))
            Cells(c.Row, 2).Resize(1, UBound(arrRes) + 1).Value = arrRes
        Next
        Set objMH = Nothing
        Set objMatch = Nothing
        Set objRegEx = Nothing
    End Sub
    

    【代码解析】
    与上面代码相同的步骤这里就不再赘述。

    匹配模式含义
    ([a-z])匹配单个小写英文字符,并提取为第一组
    ?!零宽度否定顺序环视,不消耗字符,只用于环视判断
    \1第一组匹配字符(一个或者多个)
    $行的结束标识

    aaabbccccdeeee为例看一下正则匹配过程。

    游标位置匹配组下一个字符说明
    0aa下一个字符与匹配组相同,不满足正则模式
    1aa下一个字符与匹配组相同,不满足正则模式
    2ab下一个字符与匹配组不同,满足正则模式,将被替换为a+空格
    3bb下一个字符与匹配组相同,不满足正则模式
    4bc下一个字符与匹配组不同,满足正则模式,将被替换为b+空格
    依次处理每个字符
    13e$下一个为字符结束标识,不满足正则模式

    正则替换之后的字符串为aaa bb cccc d eeee,注意字符串末尾并不会添加空格,使用Split拆分为数组,可以直接写入一行单元格内,这波操作比第一个代码更简洁。


    相关博文链接:
    VBA之正则表达式(1)-- 基础篇
    VBA之正则表达式(2)-- 批量修改公式
    VBA之正则表达式(3)-- 特殊公式计算
    VBA之正则表达式(4)-- 提取日期和金额
    VBA之正则表达式(5)-- 中文字符
    VBA之正则表达式(6)-- 设置音标格式
    VBA之正则表达式(7)-- 乾坤大挪移(数据整理)
    VBA之正则表达式(8)-- 重复字符分组
    VBA之正则表达式(9)-- 添加千分位(1/3)
    VBA之正则表达式(10)-- 添加千分位(2/3)
    VBA之正则表达式(11)-- 添加千分位(3/3)

    展开全文
  • 实例需求:数据保存在F列(公式,判断条件,whatever),需要在每个单元格引用之前添加A列指定的工作表名称+!,结果如H列所示,对于F16中的公式,由于I49已经指定工作表,所以此单元格不需要再处理,核心问题是如何...
  • 学习Excel技术,关注微信公众号:excelperfect在《VBA进阶 | 文件操作8:认识Windows Scripting Host》中,我们介绍了FileSystem对象模型。本文详解其中的Folder对象与Folders集合。Folder对象使用Folder对象可以...
  • 正则表达式校验日期

    千次阅读 2016-11-29 18:26:15
    正则表达式验证2000-2099年的日期格式MM\DD\YYYY ((((0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)\/(0[1-9]|[12][0-9]|30))|(02\/(0[1-9]|[1][0-9]|2[0-8])))\/(20[0-9]{2}))|(02\/29\/(20(0[48]|...
  •  正则表达式是通用的文本搜索和处理方案,它的知识不是VBA独有的,基本上每种语言都内置了正则表达式的功能。正则表达式的基础知识不是这里的重点,需要的朋友可以Google一下,或者参看下面的一些入门教程: ...
  • 上一篇《添加千分位(2/3)》博文讲解了实现添加千分位功能的正则表达式如下:((\.\d+[\w\W]*?)*?\d)(?=(\d{3})+(\D|$)),如果小数位于段落的最后,那么匹配结果就会有问题,可以采用添加后缀构建字符串序列的方式来...
  • 数据类型判断、转化,对话框(弹框输入、提示,返回文件路径、文件夹),空的一些情况,正则表达式语法,其他常用语句。
  • function isValidDate(dateStr, format) { if (format == null) { format = "MDY"; } format = format.toUpperCase(); if (format.length != 3) { format = "MDY"...) == ...
  • 除了可以指定正则表达式样式外,我们还可以设置一些正则表达式选项,比如让正则表达式大小写不敏感和多行匹配模式等。与 Pattern 类类似,Matcher 类也不提供公共的构造函数,我们可以从 Pattern 对象的 matcher ...
  • 正则表达式

    2020-03-04 14:23:36
    正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。 ...
  • 下面是国内 13、15、18开头的手机号正则表达式。(可根据目前国内收集号扩展前两位开头号码) ^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$   9. 判断IE的版本 IE目前还没被...
  • 正则表达式,一个十分古老而又强大的文本处理工具,仅仅用一段非常简短的表达式语句,便...正则表达式经常被用于字段或任意字符串的校验,如下面这段校验基本日期格式的JavaScript代码: 1 2 3
  • VBA 校验身份证号

    千次阅读 2020-08-30 21:39:21
    之前学过了一下正则表达式判断身份证号码是否正确,这里呢就比较简单,单纯用很多函数进行判断啦,内容不难,就是很繁琐~ 先看看实现效果,这里生成了一些随机的错误身份证号进行参照: Option Explicit Sub ...
  • 一、正则表达式简介 就其本质而言,正则表达式(或RE)是一种小型的、高度专业化的(在python中),它内嵌在python中,并通过RE模块实现。正则表达式编译成一系列字节码,然后由用C编写的匹配引擎执行。 可以用...
  • Function CI(c) 'Cells.Address.Information If IsNumeric(c) Then On Error GoTo NumErr CI = Replace(Cells(, c).Address(0, 0), 1, "") Else On Error GoTo TxtErr CI =
  • vba regexp

    千次阅读 2016-07-01 08:25:11
     正则表达式是通用的文本搜索和处理方案,它的知识不是VBA独有的,基本上每种语言都内置了正则表达式的功能。正则表达式的基础知识不是这里的重点,需要的朋友可以Google一下,或者参看下面的一些入门教程: ...
  • 给定日期判断是否是法定节假日。 给定日期判断是否是周末(周末不一定是休息日,可能需要补班)。 给定日期判断是否是需要额外补班的周末。 给定日期判断是否是休息日(包含法定节假日和不需要补班的周末)...
  • 文件夹内已经汇总了几十上百篇Doc/Docx文档,可能是各部门的总结,可能是工会入会申请,或者其它半格式化(毕竟不是表格)内容,如果没有VBA帮忙,你就要挨个打开,之后copy-n-paste里面的特定内容到你的Excel表里;...
  • 在Excel催化剂的自定义函数、文本处理等功能上,已经有大量正则表达式的封装,让一般的用户可以无需编程环境下,即可在Excel上轻松使用正则表达式。 此篇的批量替换功能,也不落空,必然要将正则表达式进行引入,...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 135
精华内容 54
热门标签
关键字:

vba正则表达式判断日期