ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 6481|回复: 33

[求助] 寻找相同韵脚的结尾字(一个比较抽象而有意义的古典诗词问题)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-3-8 15:54 | 显示全部楼层 |阅读模式
本帖最后由 ttkxssry 于 2018-3-8 15:57 编辑

大家早上好。在这里请教一个问题,是我在研究古典诗词规律时遇到的。对您的帮助,本人非常感激! 详细说明和例子见附件,供试验。

背景介绍:
“问题”表有两列,A列是原句,B列是目标列,即:欲达到的结果放在B列。
“韵脚”表有两列,B列是各个字,A列是各字对应的韵脚代码。

目的:
针对单元格内每句话最后一个字,在“韵脚”表中搜索,如果结尾字与结尾字相互在同一单元格,则用该字所对应的韵脚代码去替换该字。如果该字与其它结尾字都不在同一单元格内,则用●替换该字。

备注:判断句子的标准:以?。,:;、!为标准,只要这几个符号任意一个出现,即为一句话。


例如A2单元格,每句话最后的字分别是“草,草,老,晴,明,月,月,绝”,在“韵脚”表中搜索发现:
“草老”都在同一单元格内,对应的代码是★18,则用代码★18替换“草老”。
“晴明”在同一单元格内,对应代码是★9,则用代码★9替换“晴明”。
“月”和“月”是同一个字,对应的代码是★105,则用代码★105替换这两个月字。
“绝”则与任何结尾字都不在同一单元格,则用符号●替换绝。         最后完成的结果则放在B2内。

再举一例:A9单元格内各句最后字分别是“舟,老,沼,了,空,鸟,倒,少,晓”,在韵脚表中搜索发现:
“老倒”在同一单元格内,对应的代码是★18,则用★18替换“老倒”。
“沼了鸟少晓”在同一单元格内,对应的代码是★80,则用代码★80替换“沼了鸟少晓”。
“舟空”与任何结尾字都不在同一单元格中,则用符号●替换这两字。         最后完成的结果放在B9内。

寻找相同韵脚的结尾字-2.rar

25.09 KB, 下载次数: 13

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-3-10 12:36 | 显示全部楼层
题目比较难?我再顶一下。

TA的精华主题

TA的得分主题

发表于 2018-3-10 18:13 | 显示全部楼层
本帖最后由 opiona 于 2018-3-11 13:03 编辑

按照提示,在10楼进行了更新

  1. Sub opiona()
  2.    
  3.     Set SH1 = Worksheets("问题")
  4.     Set SH2 = Worksheets("韵脚")
  5.    
  6.     Rem 全部韵脚和汉字放入数组
  7.     ARR_YUNJIAO = SH2.Range("A2:B" & SH2.Range("A65536").End(3).Row).Value
  8.    
  9.     For IROW = 2 To SH1.Range("A65536").End(3).Row
  10.         Rem 按照标点符号拆分
  11.         ARX = Split(GetRegStr(SH1.Cells(IROW, 1).Value, "[一-龥]+[^0-9A-Za-z一-龥 ]", 0), "|")
  12.         Rem  寻找韵脚汉字
  13.         For X = 0 To UBound(ARX)
  14.             StrA = Mid(ARX(X), Len(ARX(X)) - 1, 1)  '//包括标点符号的倒数第二个
  15.             StrB = "●" '假设找不到
  16.             Rem 查找汉字对应的韵脚
  17.             For I = 1 To UBound(ARR_YUNJIAO, 1)
  18.                 If InStr(ARR_YUNJIAO(I, 2), StrA) > 0 Then
  19.                     Rem 记录此韵脚
  20.                     StrB = ARR_YUNJIAO(I, 1)
  21.                     Exit For
  22.                 End If
  23.             Next
  24.             Rem 用韵脚符号替换韵脚汉字
  25.             ARX(X) = Mid(ARX(X), 1, Len(ARX(X)) - 2) & Replace(Mid(ARX(X), Len(ARX(X)) - 1, 1), StrA, StrB) & Mid(ARX(X), Len(ARX(X)), 1)
  26.         Next
  27.         
  28.         Rem 将拆分后的数组,还原为字符串
  29.         SH1.Cells(IROW, 2).Value = Join(ARX, "")
  30.         
  31.         Rem 标注韵脚符号的颜色
  32.         BRX = Split(GetRegStr(SH1.Cells(IROW, 2).Value, "[●|★][0-9]+", 0), "|")
  33.         StratInt = 1
  34.         For X = 0 To UBound(BRX)
  35.             INTLEN = InStr(StratInt, SH1.Cells(IROW, 2).Value, BRX(X))
  36.             SH1.Cells(IROW, 2).Characters(Start:=INTLEN, Length:=Len(BRX(X))).Font.Color = -16776961
  37.             StratInt = INTLEN + Len(BRX(X))
  38.         Next
  39.         
  40.     Next
  41.    
  42. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2018-3-10 18:19 | 显示全部楼层
本帖最后由 opiona 于 2018-3-11 13:03 编辑

按照提示,在10楼进行了更新

正则方式判断的
完整代码见附件: 寻找相同韵脚.rar (30.5 KB, 下载次数: 9)

点评

与题意有所不同:没有相同韵脚的要替换为“●”  发表于 2018-3-11 10:04

TA的精华主题

TA的得分主题

发表于 2018-3-10 19:47 | 显示全部楼层
ttkxssry 发表于 2018-3-10 12:36
题目比较难?我再顶一下。

试试:

  1. Sub ShengYun()
  2. Dim brr, bd, r1, r2, ij, k, b, f As Boolean
  3. bd = ",,。.、;;::!!"
  4. With Sheets("韵脚")
  5.      r2 = .[A65536].End(xlUp).Row
  6.      brr = .Range("A1:B" & r2).Value
  7. End With
  8. With Sheets("问题")
  9.      r1 = .[A65536].End(xlUp).Row
  10.      .Range("B2:B" & r1).ClearContents
  11.      For i = 2 To r1
  12.          .Cells(i, 2) = .Cells(i, 1)
  13.          j = 1
  14.          Do
  15.              If InStr(bd, Mid(.Cells(i, 2), j, 1)) Then
  16.                 f = False
  17.                 For k = 2 To UBound(brr)
  18.                     If InStr(brr(k, 2), Mid(.Cells(i, 2), j - 1, 1)) Then
  19.                        .Cells(i, 2).Characters(j - 1, 1).Text = brr(k, 1)
  20.                        j = j + Len(brr(k, 1))
  21.                        f = True
  22.                        Exit For
  23.                     End If
  24.                 Next
  25.                 If f = False Then
  26.                     .Cells(i, 2).Characters(j - 1, 1).Text = "●"
  27.                 End If
  28.              End If
  29.              j = j + 1
  30.              p = Len(.Cells(i, 2))
  31.              If j > p Then Exit Do
  32.          Loop
  33.      Next
  34. End With
  35. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2018-3-10 19:49 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-3-10 20:55 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
同一个字有几个不同的韵脚,还是会有不确定的。
比如“”倒“”,B18、B19都有,怎么确定是哪一个?

TA的精华主题

TA的得分主题

发表于 2018-3-10 21:47 | 显示全部楼层
学习下正则:
  1. Sub ShengYun2()
  2. Dim RegEx1, RegEx2, arr, brr, r1, r2, i, j, a, b, c, d, sr, st, s, f As Boolean
  3. Set RegEx1 = CreateObject("VBSCRIPT.REGEXP")
  4. Set RegEx2 = CreateObject("VBSCRIPT.REGEXP")
  5. On Error Resume Next
  6. Application.ScreenUpdating = False
  7. RegEx1.Global = True
  8. RegEx1.IgnoreCase = True
  9. RegEx1.Pattern = "[!-~]"
  10. RegEx2.Global = True
  11. RegEx2.IgnoreCase = True
  12. RegEx2.Pattern = "[\?|、|!|,|。|【}】]"
  13. With Sheets("韵脚")
  14.      r2 = .[A65536].End(xlUp).Row
  15.      brr = .Range("A1:B" & r2).Value
  16. End With
  17. With Sheets("问题")
  18.      r1 = .[A65536].End(xlUp).Row
  19.      .Range("B2:B" & r1).ClearContents
  20.      arr = .Range("A1:B" & r1).Value
  21.      For i = 2 To UBound(arr)
  22.          a = arr(i, 1)
  23.          b = RegEx1.Replace(a, "*")
  24.          c = Replace(b, "*", "")
  25.          d = RegEx2.Replace(c, "|")
  26.          sr = Split(d, "|")
  27.          Set st = RegEx2.Execute(a)
  28.          For s = 0 To UBound(sr)
  29.              f = False
  30.              For j = 2 To UBound(brr)
  31.                  If InStr(brr(j, 2), Right(sr(s), 1)) Then
  32.                     sr(s) = Left(sr(s), Len(sr(s)) - 1) & brr(j, 1) & st(s)
  33.                     f = True
  34.                  End If
  35.              Next
  36.              If f = False Then
  37.                 sr(s) = Left(sr(s), Len(sr(s)) - 1) & "●" & st(s)
  38.              End If
  39.          Next
  40.          arr(i, 2) = Join(sr, "")
  41.      Next
  42.      .Range("A1").Resize(UBound(arr), UBound(arr, 2)) = arr
  43. End With
  44. Erase arr, brr
  45. Set RegEx1 = Nothing
  46. Set RegEx2 = Nothing
  47. Application.ScreenUpdating = True
  48. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2018-3-11 10:25 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
将颜色也设置下,见附件:

寻找相同韵脚的结尾字-0.rar

38.13 KB, 下载次数: 2

TA的精华主题

TA的得分主题

发表于 2018-3-11 12:58 | 显示全部楼层
本帖最后由 opiona 于 2018-3-11 12:59 编辑

根据指正,进行了修改
完整代码见附件: 寻找相同韵脚.rar (31.54 KB, 下载次数: 6)

多次出现的韵脚,显示数字
只出现一次的,用圆圈替换

  1. Sub opiona()
  2.    
  3.     Set SH1 = Worksheets("问题")
  4.     Set SH2 = Worksheets("韵脚")
  5.    
  6.     Rem 全部韵脚和汉字放入数组
  7.     ARR_YUNJIAO = SH2.Range("A2:B" & SH2.Range("A65536").End(3).Row).Value
  8.    
  9.     For IROW = 2 To SH1.Range("A65536").End(3).Row
  10.         Rem 按照标点符号拆分
  11.         ARX = Split(GetRegStr(SH1.Cells(IROW, 1).Value, "[一-龥]+[^0-9A-Za-z一-龥 ]", 0), "|")
  12.         
  13.         Rem  寻找全部韵脚汉字
  14.         ReDim CRX(0)
  15.         CLEN = 0
  16.         For X = 0 To UBound(ARX)
  17.             StrA = Mid(ARX(X), Len(ARX(X)) - 1, 1)  '//包括标点符号的倒数第二个
  18.             For I = 1 To UBound(ARR_YUNJIAO, 1)
  19.                 If InStr(ARR_YUNJIAO(I, 2), StrA) > 0 Then
  20.                     Rem 记录此韵脚
  21.                     ReDim Preserve CRX(CLEN)
  22.                     CRX(CLEN) = ARR_YUNJIAO(I, 1)
  23.                     CLEN = CLEN + 1
  24.                     Exit For
  25.                 End If
  26.             Next
  27.         Next
  28.         
  29.         For X = 0 To UBound(ARX)
  30.             StrA = Mid(ARX(X), Len(ARX(X)) - 1, 1)  '//包括标点符号的倒数第二个
  31.             Rem 查找汉字对应的韵脚
  32.             XX = 0
  33.             For I = 1 To UBound(ARR_YUNJIAO, 1)
  34.                 If InStr(ARR_YUNJIAO(I, 2), StrA) > 0 Then
  35.                     Rem 记录此韵脚
  36.                     StrB = ARR_YUNJIAO(I, 1)
  37.                     For Z = 0 To UBound(CRX)
  38.                         If StrB = CRX(Z) Then
  39.                             XX = XX + 1  '//记录此韵脚出现的次数
  40.                         End If
  41.                     Next
  42.                     Exit For
  43.                 End If
  44.             Next
  45.             Rem 2个及以上则用韵脚符号替换韵脚汉字
  46.             If XX > 1 Then
  47.                 ARX(X) = Mid(ARX(X), 1, Len(ARX(X)) - 2) & Replace(Mid(ARX(X), Len(ARX(X)) - 1, 1), StrA, StrB) & Mid(ARX(X), Len(ARX(X)), 1)
  48.             Else
  49.                 Rem 只有一个 则是:●
  50.                 ARX(X) = Mid(ARX(X), 1, Len(ARX(X)) - 2) & Replace(Mid(ARX(X), Len(ARX(X)) - 1, 1), StrA, "●") & Mid(ARX(X), Len(ARX(X)), 1)
  51.             End If
  52.         Next
  53.         
  54.         Rem 将拆分后的数组,还原为字符串
  55.         SH1.Cells(IROW, 2).Value = Join(ARX, "")
  56.         
  57.         Rem 标注韵脚符号的颜色
  58.         BRX = Split(GetRegStr(SH1.Cells(IROW, 2).Value, "[★][0-9]+", 0), "|")
  59.         StratInt = 1
  60.         For X = 0 To UBound(BRX)
  61.             INTLEN = InStr(StratInt, SH1.Cells(IROW, 2).Value, BRX(X))
  62.             SH1.Cells(IROW, 2).Characters(Start:=INTLEN, Length:=Len(BRX(X))).Font.Color = -16776961
  63.             StratInt = INTLEN + Len(BRX(X))
  64.         Next
  65.         
  66.     Next
  67.    
  68. End Sub
复制代码

评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-5-22 20:26 , Processed in 0.039327 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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