Access交流中心

北京 | 上海 | 天津 | 重庆 | 广州 | 深圳 | 珠海 | 汕头 | 佛山 | 中山 | 东莞 | 南京 | 苏州 | 无锡 | 常州 | 南通 | 扬州 | 徐州 | 杭州 | 温州 | 宁波 | 台州 | 福州 | 厦门 | 泉州 | 龙岩 | 合肥 | 芜湖 | 成都 | 遂宁 | 长沙 | 株洲 | 湘潭 | 武汉 | 南昌 | 济南 | 青岛 | 烟台 | 潍坊 | 淄博 | 济宁 | 太原 | 郑州 | 石家庄 | 保定 | 唐山 | 西安 | 大连 | 沈阳 | 长春 | 昆明 | 兰州 | 哈尔滨 | 佳木斯 | 南宁 | 桂林 | 海口 | 贵阳 | 西宁 | 乌鲁木齐 | 包头 |

回复 加入收藏帖  复制
我要提问 帖子上移

[5分]请教一个比较复杂的正则表达式问题

煮江品茶 等级: 荣誉管理员★★★★★ 积分:5136 金币:17920 来自:武汉Access交流中心 发表于:2013-01-26 20:12:48   已结帖
楼主

我在写一个程序,为了简化输入需要写一个与正则表达式有关的函数,我希望输入一个字符串,这个字符串中包含形如:sum(v(1,1):v(3,3))的子字符串。
如何用一个自定义函数将这个子字符串替换为形如:
(v(1,1)+v(1,2)+v(1,3)+v(2,1)+v(2,2)+v(2,3)+v(3,1)+v(3,2)+v(3,3))
的子字符串,并返回替换后的字符串。由于对正则表达式不太熟悉,望帮忙写一个自定义函数。谢谢!!!

 

access培训  诚聘access开发人员

    煮江品茶
      获得社区协助:请教问题(即发帖)11篇,其中获得解决的7篇;
      协助社区成员:协助他人(即回帖)4989篇,其中被设为【最佳答案】的1581篇;
      协助我们社区:发布技术文章448篇,邀请了47名新会员注册本社区(如何邀请会员注册,详见:http://www.accessoft.com/sitehelp.asp)。
Top

扫描下方工作人员的微信二维码加微信,邀您加入Access课堂微信群,进入一个技术交际圈:

网站工作人员微信

殷小宝 等级:一星会员▲ 积分:724 金币:800 来自:芜湖Access交流中心 发表于2013/1/26 20:52:47 
1楼 得分: 0

Funtion arraysum (A(a,b)&":"&A(c,d)) As String

Dim i,j As Integer

Dim B As Variant

For i=a To c

  For j=b To d

  arraysum=arraysum &" +"& B(i,j)

  Next

Next

End Fuction



    很高兴与您就本帖子进行交流,如果我的回答已经解决了您的问题,请点击上方的“最佳答案”,这样本帖子就不会在“待解决问题区”显示了,我也将获得2个积分奖励,并不会减少您的积分!
    殷小宝
      获得社区协助:请教问题(即发帖)122篇,其中获得解决的120篇;
      协助社区成员:协助他人(即回帖)671篇,其中被设为【最佳答案】的175篇;
      协助我们社区:发布技术文章20篇,邀请了3名新会员注册本社区(如何邀请会员注册,详见:http://www.accessoft.com/sitehelp.asp)。
殷小宝 等级:一星会员▲ 积分:724 金币:800 来自:芜湖Access交流中心 发表于2013/1/26 20:56:33 
2楼 得分: 0

Funtion arraysum (A(a,b)&":"&A(c,d)) As String

Dim i,j As Integer

For i=a To c

  For j=b To d

  arraysum=arraysum &" +" & A(i,j)

  Next

Next

End Fuction



    很高兴与您就本帖子进行交流,如果我的回答已经解决了您的问题,请点击上方的“最佳答案”,这样本帖子就不会在“待解决问题区”显示了,我也将获得2个积分奖励,并不会减少您的积分!
    殷小宝
      获得社区协助:请教问题(即发帖)122篇,其中获得解决的120篇;
      协助社区成员:协助他人(即回帖)671篇,其中被设为【最佳答案】的175篇;
      协助我们社区:发布技术文章20篇,邀请了3名新会员注册本社区(如何邀请会员注册,详见:http://www.accessoft.com/sitehelp.asp)。
煮江品茶 等级:荣誉管理员★★★★★ 积分:5136 金币:17920 来自:武汉Access交流中心 发表于2013/1/26 21:58:17 
3楼 得分: 0

呵呵,没那么简单。

诸如:以下的字符串,都能被替换为加号连接的数组字符串。这是正则表达式问题,其他方法解不出来的。

“round(sum(v(1,2):v(2,4)/5,2)”

"iif(sum(v(2,2):v(4,4))=0,0,1/sum(v(2,2):v(4,4)))"



    煮江品茶
      获得社区协助:请教问题(即发帖)11篇,其中获得解决的7篇;
      协助社区成员:协助他人(即回帖)4989篇,其中被设为【最佳答案】的1581篇;
      协助我们社区:发布技术文章448篇,邀请了47名新会员注册本社区(如何邀请会员注册,详见:http://www.accessoft.com/sitehelp.asp)。
殷小宝 等级:一星会员▲ 积分:724 金币:800 来自:芜湖Access交流中心 发表于2013/1/27 10:24:35 最佳答案
4楼 得分: 5
我知道是没有这么简单,否则老师不会发贴了。

    很高兴与您就本帖子进行交流,如果我的回答已经解决了您的问题,请点击上方的“最佳答案”,这样本帖子就不会在“待解决问题区”显示了,我也将获得2个积分奖励,并不会减少您的积分!
    殷小宝
      获得社区协助:请教问题(即发帖)122篇,其中获得解决的120篇;
      协助社区成员:协助他人(即回帖)671篇,其中被设为【最佳答案】的175篇;
      协助我们社区:发布技术文章20篇,邀请了3名新会员注册本社区(如何邀请会员注册,详见:http://www.accessoft.com/sitehelp.asp)。
何保辛 等级:Access资深专家★★★★★ 积分:1147 金币:1080 来自:深圳Access交流中心 发表于2015/2/7 17:17:51 
5楼 得分: 0

给你第一版吧,只是把文本表达式转换为 VBA表达式。
我认为最有效率的应该是把 数组传过去 马上运算,所以那个会是第二版。
不过这两版都是耗点资源的,regexp 已经是非常高效的文本处理器,但是如果你会做非常强大的“编译器”的话,一段文本的处理是错误的!
正确应该是一个一个字符读入,处理当前的“语法错误”,和使用堆栈来运算 “当前值”的。

Function ggg(str As String)

Dim re As RegExp, m As MatchCollection, sm As SubMatches, vs() As Variant, vsqty As Long

vsqty = 0
Set re = New RegExp
re.Global = True
re.IgnoreCase = True
re.Multiline = True

ReDim vs(vsqty)
re.Pattern = "(\w+)\(([\w\d]+)\((\d+),(\d+)\)\:([\w\d]+)\((\d+),(\d+)\)\)"

ggg = str
Set m = re.Execute(str)
Do While m.Count > 0
    Set sm = m(0).SubMatches
    vsqty = 0
    ReDim vs(0)
    vs(0) = "[SyntaxError]"
    If InStr("sum average", sm(0)) Then
        If sm(1) = sm(4) Then
    
            sti = IIf(sm(2) < sm(5), 1, -1)
            stj = IIf(sm(3) < sm(6), 1, -1)
            For i = sm(2) To sm(5) Step sti
                For j = sm(3) To sm(6) Step stj
                    ReDim Preserve vs(vsqty)
                    vs(vsqty) = sm(1) & "(" & i & "," & j & ")"
                    vsqty = vsqty + 1
                Next
            Next
            
        End If
        If sm(0) = "sum" Then
            rep = "(" & Join(vs, "+") & ")"
        ElseIf sm(0) = "average" Then
            rep = "(" & Join(vs, "+") & ")/" & vsqty
        End If
    End If
        
    ggg = Replace(ggg, m(0), rep, 1, 1)
        
    Set m = re.Execute(ggg)
    
Loop


End Function

第一版执行结果:
? ggg("round(sum(v(1,2):v(2,4))/5,2)+average(v(1,2):v(2,3))*3")

round((v(1,2)+v(1,3)+v(1,4)+v(2,2)+v(2,3)+v(2,4))/5,2)+(v(1,2)+v(1,3)+v(2,2)+v(2,3))/4*3

这个版本让你把表达式转换成为 VBA 表达式,自己eval 吧!


第二版,需要做再说吧!

第三版,单字节处理版,付费的可以帮你做个动态语法编译器出来的! 

给你第一版吧,只是把文本表达式转换为 VBA表达式。
我认为最有效率的应该是把 数组传过去 马上运算,所以那个会是第二版。
不过这两版都是耗点资源的,regexp 已经是非常高效的文本处理器,但是如果你会做非常强大的“编译器”的话,一段文本的处理是错误的!
正确应该是一个一个字符读入,处理当前的“语法错误”,和使用堆栈来运算 “当前值”的。

Function ggg(str As String)

Dim re As RegExp, m As MatchCollection, sm As SubMatches, vs() As Variant, vsqty As Long

vsqty = 0
Set re = New RegExp
re.Global = True
re.IgnoreCase = True
re.Multiline = True

ReDim vs(vsqty)
re.Pattern = "(\w+)\(([\w\d]+)\((\d+),(\d+)\)\:([\w\d]+)\((\d+),(\d+)\)\)"

ggg = str
Set m = re.Execute(str)
Do While m.Count > 0
    Set sm = m(0).SubMatches
    vsqty = 0
    ReDim vs(0)
    vs(0) = "[SyntaxError]"
    If InStr("sum average", sm(0)) Then
        If sm(1) = sm(4) Then
    
            sti = IIf(sm(2) < sm(5), 1, -1)
            stj = IIf(sm(3) < sm(6), 1, -1)
            For i = sm(2) To sm(5) Step sti
                For j = sm(3) To sm(6) Step stj
                    ReDim Preserve vs(vsqty)
                    vs(vsqty) = sm(1) & "(" & i & "," & j & ")"
                    vsqty = vsqty + 1
                Next
            Next
            
        End If
        If sm(0) = "sum" Then
            rep = "(" & Join(vs, "+") & ")"
        ElseIf sm(0) = "average" Then
            rep = "(" & Join(vs, "+") & ")/" & vsqty
        End If
    End If
        
    ggg = Replace(ggg, m(0), rep, 1, 1)
        
    Set m = re.Execute(ggg)
    
Loop


End Function

第一版执行结果:
? ggg("round(sum(v(1,2):v(2,4))/5,2)+average(v(1,2):v(2,3))*3")

round((v(1,2)+v(1,3)+v(1,4)+v(2,2)+v(2,3)+v(2,4))/5,2)+(v(1,2)+v(1,3)+v(2,2)+v(2,3))/4*3

这个版本让你把表达式转换成为 VBA 表达式,自己eval 吧!


第二版,需要做再说吧!

第三版,单字节处理版,付费的可以帮你做个动态语法编译器出来的! 



    很高兴与您就本帖子进行交流,如果我的回答已经解决了您的问题,请点击上方的“最佳答案”,这样本帖子就不会在“待解决问题区”显示了,我也将获得2个积分奖励,并不会减少您的积分!
    何保辛
      获得社区协助:请教问题(即发帖)5篇,其中获得解决的0篇;
      协助社区成员:协助他人(即回帖)419篇,其中被设为【最佳答案】的114篇;
      协助我们社区:发布技术文章27篇,邀请了1名新会员注册本社区(如何邀请会员注册,详见:http://www.accessoft.com/sitehelp.asp)。
总记录:5篇  页次:1/1 9 1 :
您还没有在Access软件网登录不能回复帖子
  • 你没有登录,请点击后面链接登录:登录
  • 如果你没有注册,请点击后面链接注册:注册,注册完成后,请再次访问本页功能。