ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
Python自动化办公应用大全 Excel 2021函数公式学习大典 Kutools for Office 套件发布 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: weiyingde

[已解决] 正则自定义易位函数出现BUG,求修复。

[复制链接]

TA的精华主题

TA的得分主题

发表于 2025-3-20 15:07 | 显示全部楼层
weiyingde 发表于 2025-3-20 13:04
谢谢大侠回复。我检查了原始数据,发现“liàn liàn (恋恋)不舍”前括号前有个空格,删除后”liàn lià ...

看了下,有两个问题吧,第一应该使用最后一个pattern,但是使用了第三个,所以我测试是取消了前面几个就对了,然后这里是有两个,global需要true了,然后需要循环取出match了,所以情况是这样了,正则我也是半桶水,基本是够用,不够精通的。
image.png
image.png

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2025-3-20 15:07 | 显示全部楼层

恳请大虾再看看,到底是什么原因。

TA的精华主题

TA的得分主题

发表于 2025-3-20 15:08 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
代码如下。。。
Function 易位(txt As String) As String
    Dim regex As Object, match As Object
    Set regex = CreateObject("VBScript.RegExp")
   
    With regex
        .Global = True
        .IgnoreCase = False
        .MultiLine = True
   
        ' 按优先级定义模式数组(类型,正则表达式,替换模板)
        Dim patterns(0) As Variant
        '        patterns(0) = Array("A", "([一-龢]{2,})\(([a-zāáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜêü]+(?: [a-zāáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜêü]+)+)\)")
        '        patterns(1) = Array("C", "([一-龢])(\()([a-zāáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜêü ]+)(\))([一-龢]+)", "$3$2$1$4$5")
        '        patterns(2) = Array("D", "([一-龢]+)([a-zāáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜêü ]+)(\()([一-龢]+)(\))([一-龢]*)", "$1$4$3$2$5$6")
        patterns(0) = Array("B", "([a-zāáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜêü]+(?: [a-zāáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜêü]+)*)\(([一-龢]+)\)")
   
        Dim i As Long
        Dim startPos As Long
        Dim length As Long
        Dim replacement As String
        Dim hz As String, py As String, pyCount As Long, hzCount As Long
        For i = LBound(patterns) To UBound(patterns)
            .Pattern = patterns(i)(1)
            If .test(txt) Then
                Set matchs = .Execute(txt)
                For Each match In matchs
                    startPos = match.FirstIndex + 1
                    length = match.length
                    Select Case patterns(i)(0)
                        Case "A", "B"                          ' 处理复杂逻辑
                            If patterns(i)(0) = "A" Then
                                hz = match.SubMatches(0)
                                py = match.SubMatches(1)
                            Else
                                py = match.SubMatches(0)
                                hz = match.SubMatches(1)
                            End If
   
                            pyCount = UBound(Split(py, " ")) + 1
                            hzCount = Len(hz)
   
                            If pyCount = hzCount Then
                                replacement = .Replace(match.Value, "$2($1)")
                            Else
                                If patterns(i)(0) = "A" Then
                                    replacement = Left(hz, hzCount - pyCount) & py & "(" & Right(hz, pyCount) & ")"
                                Else
                                    replacement = Left(hz, pyCount) & "(" & py & ")"
                                End If
                            End If
                        Case Else                              ' 简单替换逻辑
                            replacement = .Replace(match.Value, patterns(i)(2))
                    End Select
                    txt = Left(txt, startPos - 1) & replacement & Mid(txt, startPos + length)
                Next
                易位 = txt
                Exit Function
            End If
        Next
    End With
   
    易位 = txt                                                   ' 无匹配时返回原文本
End Function

TA的精华主题

TA的得分主题

发表于 2025-3-20 15:09 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2025-3-20 15:37 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2025-3-20 16:51 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
weiyingde 发表于 2025-3-20 15:06
恳请大虾再看看,到底是什么原因。

365版公式:
=REDUCE(A2,SEQUENCE(9),LAMBDA(t,p,LET(n,INDEX(p,1),REGEXREPLACE(t,"([^一-龥\s]+(?:\s+[^一-龥\s]+){" & n -1 & "})\(([一-龥]{" & n & "})\)","$2($1)"))))

自定义函数,原理与上相同

  1. Dim pats$(1 To 9) '分别保存:括号内1个至9个汉字对应的正则表达式
  2. Function 易位(ByVal txt As String) As String
  3.     With CreateObject("VBScript.RegExp")
  4.         Do
  5.             .Pattern = "\([一-龥]+\)"
  6.             If .test(txt) = False Then Exit Do
  7.             Set ma = .Execute(txt)(0)
  8.             n = ma.length - 2 '得到括号内汉字的个数
  9.             pats(n) = "([^一-龥\s]+(?:\s+[^一-龥\s]+){" & n - 1 & "})\(([一-龥]{" & n & "})\)"
  10.             .Pattern = pats(n)
  11.             txt = .Replace(txt, "$2($1)")
  12.         Loop
  13.     End With
  14.     易位 = txt
  15. End Function
复制代码
image.jpg

测试结果.rar (26.45 KB, 下载次数: 12)


评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2025-3-20 18:02 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
现在的新函数太强了,收藏学习!

TA的精华主题

TA的得分主题

 楼主| 发表于 2025-3-21 06:34 来自手机 | 显示全部楼层
ggmmlol  2025-3-20 16:51
365湫
=REDUCE(A2,SEQUENCE(9),LAMBDA(t,p,LET(n,INDEX(p,1),REGEXREPLACE(t,"([^-\s]+(?:\s+ ...

ллдúúлл

TA的精华主题

TA的得分主题

 楼主| 发表于 2025-3-21 07:08 | 显示全部楼层
本帖最后由 weiyingde 于 2025-3-21 13:11 编辑
ggmmlol 发表于 2025-3-20 16:51
365版公式:
=REDUCE(A2,SEQUENCE(9),LAMBDA(t,p,LET(n,INDEX(p,1),REGEXREPLACE(t,"([^一-龥\s]+(?:\s+ ...

你的自定义函数代码简洁,非常好,若在此基础上进行优化,必然取得非常满意的效果。
优化的目的在于增强他的适配性、通用性和灵活性。具体说要达到的目的是:
1、支持长文本,多内容(多个括号)互换。
2、支持多形式,比如:拼音(汉字)汉字(拼音)拼音(汉字)、汉字(拼音)拼音(汉字)拼音(汉字)汉字、拼音(汉字)汉字(拼音)汉字(拼音)……
3、支持多音节。比如,若是:汉字(拼音)形式,必须根据拼音的音节数(注意:拼音的音节之间有英文空格隔开)确定互换的汉字数量。
最后用下面的内容进行测试:
还有(yǒu)紫pǔ táo(葡萄)的彩色(cǎi sè)的叮咛(dīng níng)
绿荫(lǜ yīn)zhē bì(遮蔽)了村zhuāng(庄)的路口和烟cōng(囱)

我知道这个要求有些高,难为大侠了

TA的精华主题

TA的得分主题

 楼主| 发表于 2025-3-21 10:20 | 显示全部楼层
针对上一楼的情况再次请教,盼高手援手指教。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-12-15 03:23 , Processed in 1.031335 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表