计算和突出短语中的关键字

Posted

技术标签:

【中文标题】计算和突出短语中的关键字【英文标题】:Count and Highlight keywords within phrases 【发布时间】:2015-12-27 22:14:07 【问题描述】:

我有一个包含两列的 Excel 表。第一列是关键短语,第二列是消息。关键短语可能出现在消息列中。我需要知道消息列中出现了多少次关键短语。请提出一些好的和简单的查找方法。

关键字是一列,消息是第二列。消息列是 1 个或多于 1 个关键短语的组合(连接)。我需要找出每条消息包含多少个关键短语。

【问题讨论】:

如果 Excel 数据是 SQL 查询的结果,我建议使用子查询或分区来雕刻 T-SQL,以便与其余数据一起提供结果。 messages 列可以有多个关键字出现在第一列中。例如,如果关键短语是“这是要测试的”,那么这个字符串可以作为子字符串出现在消息列中的许多行中。例如“你好世界;这是要测试的;这也在测试中;”。此类值在 B 列中可用。 是的,这就是子查询在 SELECT 语句中所做的事情。 【参考方案1】:

您可能能够使用模块子过程收集有效的计数,该过程在内存数组中执行所有数学运算并将计数返回到工作表。

      

我使用了一些标准的Lorem Ipsum 关键字和短语来创建上述示例数据。

点击Alt+F11,当VBE打开时,立即使用下拉菜单插入►模块(Alt+I,M)。将以下内容粘贴到标题为 Book1 - Module1 (Code) 的新模块代码表中。

Option Explicit

Sub count_strings_inside_strings()
    Dim rw As Long, lr As Long
    Dim k As Long, p As Long, vKEYs As Variant, vPHRASEs As Variant, vCOUNTs As Variant

    ReDim vKEYs(0)
    ReDim vPHRASEs(0)

    With Worksheets("Sheet1")   '<~~ set to the correct worksheet name\
        'populate the vKEYs array
        For rw = 2 To .Cells(Rows.Count, 1).End(xlUp).Row
            vKEYs(UBound(vKEYs)) = LCase(.Cells(rw, 1).Value2)
            ReDim Preserve vKEYs(UBound(vKEYs) + 1)
        Next rw
        ReDim Preserve vKEYs(UBound(vKEYs) - 1)

        'populate the vPHRASEs array
        For rw = 2 To .Cells(Rows.Count, 2).End(xlUp).Row
            vPHRASEs(UBound(vPHRASEs)) = LCase(.Cells(rw, 2).Value2)
            ReDim Preserve vPHRASEs(UBound(vPHRASEs) + 1)
        Next rw
        ReDim Preserve vPHRASEs(UBound(vPHRASEs) - 1)
        ReDim vCOUNTs(0 To UBound(vPHRASEs))

        'perform the counts
        For p = LBound(vPHRASEs) To UBound(vPHRASEs)
            For k = LBound(vKEYs) To UBound(vKEYs)
                vCOUNTs(p) = CInt(vCOUNTs(p)) + _
                    (Len(vPHRASEs(p)) - Len(Replace(vPHRASEs(p), vKEYs(k), vbNullString))) / Len(vKEYs(k))
            Next k
        Next p

        'return the counts to the worksheet
        .Cells(2, 3).Resize(UBound(vCOUNTs) + 1, 1) = Application.Transpose(vCOUNTs)

        'run the helper procedure to Blue|Bold all of the found keywords within the phrases
        Call key_in_phrase_helper(vKEYs, .Range(.Cells(2, 2), .Cells(Rows.Count, 2).End(xlUp)))

    End With
End Sub

Sub key_in_phrase_helper(vKYs As Variant, rPHRSs As Range)
    Dim p As Long, r As Long, v As Long

    With rPHRSs
        For r = 1 To rPHRSs.Rows.Count
            .Cells(r, 1) = .Cells(r, 1).Value2
            For v = LBound(vKYs) To UBound(vKYs)
                p = 0
                Do While CBool(InStr(p + 1, .Cells(r, 1).Value2, vKYs(v), vbTextCompare))
                    p = InStr(p + 1, .Cells(r, 1).Value2, vKYs(v), vbTextCompare)
                    Debug.Print vKYs(v)
                    With .Cells(r, 1).Characters(Start:=p, Length:=Len(vKYs(v))).Font
                        .Bold = True
                        .ColorIndex = 5
                    End With
                Loop
            Next v
        Next r
    End With
End Sub

您可能必须重命名要在第 5th 代码行中处理的工作表。我还包含了一个帮助程序,它使用 Blue|Bold 字体识别短语中的关键词。如果不需要,注释掉或删除第一个子过程底部的Call key_in_phrase_helper(...) 行。

点击 Alt+Q 返回您的工作表。点击Alt+F8打开Macros对话框和Run子程序。如果您的数据与我汇总的示例数据相似,那么您应该得到类似的结果。

      


¹ 这些是一些高级方法,但我认为它们也是解决您的问题的最佳方法。如果您有具体问题而您自己的研究没有充分解释,我会尝试在评论部分解决这些问题。我为创建此解决方案而创建的示例工作簿可应要求提供。

【讨论】:

这太棒了。非常感谢您的回复。效果很好。 很高兴听到这个消息。在此过程中我不得不做出一些假设,但似乎我猜对了。 需要更多帮助。一些关键短语有一些日期和数字,在原始消息中可能会有所不同,但消息的其余部分保持不变。例如,关键短语是“Id 创建 xx-xx-xx 失败”,消息是“Id 创建 9823023 失败”。你能帮我解决这个问题吗?它在匹配时会忽略数字。 添加该功能意味着涉及 RegEx(正则表达式)和一些模糊逻辑。简而言之,这会破坏这项工作并需要完全重写。鉴于缺乏示例关键字和短语导致了这个缺点,为什么不close off this question 并启动另一个可以概述新要求的地方。您甚至可以在此处就新问题发表快速评论,因为我对如何继续有一些想法。 我不能在下一周发布另一个问题:(【参考方案2】:

您可以从第二行开始使用此公式COUNTIF(B:B;"*"&amp;A2&amp;"*")

【讨论】:

你能帮我理解一下吗。对不起,我不是excel的常客。 B:B 是指整个 B 列,其中您有消息。该公式将查看它。 A2 是指 A 列第二行中您拥有密钥的单元格。 Asterisk(*) 是用于搜索的通配符。与号 (&) 是用于连接字符串的运算符。例如,如果您在 A 列中有键“excel”,在 B 列中有消息“Excel 2016 与 Windows 10 兼容”,则需要构建搜索模式*excel*。这就是为什么在公式参数的开头和结尾使用字符串部分 "*" 的原因。然后使用 &amp; 将它与密钥连接起来。 谢谢,但是很抱歉,我有一个疑问。这是否会仅将一个元素 A2 与整个 B:B 列进行比较?我需要将 A 列的所有值与 B 列的所有值进行比较。 @Megan,尝试将公式=(SUMPRODUCT(LEN(B:B))-SUMPRODUCT(LEN(SUBSTITUTE(B:B;A2;""))))/LEN(A2) 插入单元格C2,然后向下展开

以上是关于计算和突出短语中的关键字的主要内容,如果未能解决你的问题,请参考以下文章

解析短语和关键字的搜索字符串

js 关于运算顺序的问题

ESLint 规则在 Angular 中排除某些关键字和短语?

PHP 使用PHP突出显示短语中的特定单词

关键字抽取论文阅读笔记

突出搜索中的多个关键字