【问题标题】:Trying to extract a string of text pattern from the beginning and the end of a cell in Excel试图从Excel中单元格的开头和结尾提取一串文本模式
【发布时间】:2020-12-13 13:14:54
【问题描述】:

我有以下数据以及我希望在列结果中看到的内容:

Data Result
PN 65011:2020text text text PN 65011:2020 PN 65011:2020, PN 65011:2020
PN 45014-1:2017text text text text PN 65014-1:2017 PN 8726-1:2017/P11:2020 PN 45014-1:2017, PN 65014-1:2017, PN 8726-1:2017/P11:2020
PN 6534:2020text text text text PN 6534:2020
PN 65014-1:2017text text text text PN 65014-1:2017/PC1:2013 PN 65014-1:2017,PN 65014-1:2017/PC1:2013
PN ESO 67345:2019text text text PN 65018-1:2019/PC2:2020 PN ESO 67345:2019, PN 65018-1:2019/PC2:2020
PN ESO/EOC 5320:2013text text text PN ESO 27380:2019 PN 65015-1:2020/PC:2021 PN ESO/EOC 5320:2013, PN ESO 27380:2019, PN 65015-1:2020/PC:2021

我用过="PN "&TEXTJOIN(", PN ",1,IF(ISNUMBER(SEARCH("/",TRIM(MID(SUBSTITUTE(A2,"PN ",REPT(" ",LEN(A2))),(ROW(INDIRECT("1:"&LEN(A2))))*LEN(A2)-(LEN(A2)-1),LEN(A2))))),TRIM(MID(SUBSTITUTE(A2,"PN ",REPT(" ",LEN(A2))),(ROW(INDIRECT("1:"&LEN(A2))))*LEN(A2)-(LEN(A2)-1),LEN(A2))),LEFT(TRIM(MID(SUBSTITUTE(A2,"PN ",REPT(" ",LEN(A2))),(ROW(INDIRECT("1:"&LEN(A2))))*LEN(A2)-(LEN(A2)-1),LEN(A2))),MIN(IFERROR(FIND({" "},LOWER(TRIM(MID(SUBSTITUTE(A2,"PN ",REPT(" ",LEN(A2))),(ROW(INDIRECT("1:"&LEN(A2))))*LEN(A2)-(LEN(A2)-1),LEN(A2))))),""))-1)))

除了最后一行(PN ESO 5320:2013)之外,我几乎得到了我想看到的内容,我没有得到数字。它停在 PN ESO。像这样:

Data Result
PN ESO/EOC 5320:2013text text PN ESO 27380:2019 text PN 65015-1:2020/PC:2021 PN ESO/EOC, PN ESO

关于如何获得完整参考的任何想法?

非常感谢您。

【问题讨论】:

  • 第一个引用和文本之间没有空格,而对于其他引用,总是有空格。 “文本文本文本”是长度不同的参考文献的标题,它们的相关性不足以被提取,因为如果我知道参考文献,我将能够在数据库中检索它们。它是 O365。

标签: excel string text excel-formula extract


【解决方案1】:

这是一个关于如何使用 Excel O365 处理此问题的示例

B2中的公式:

=TEXTJOIN(", ",,LET(X,FILTERXML("<t><s>"&SUBSTITUTE(A2,"PN ","</s><s>PN ")&"</s></t>","//s[position() > 1]"),Y,LEFT(X,FIND("|",SUBSTITUTE(X,":","|",LEN(X)-LEN(SUBSTITUTE(X,":",""))))+4),Y))

这里的想法是首先将“PN”的所有实例SUBSTITUTE() 转换为有效的xpath 构造。然后我们使用FILTERXML() 将所有值作为数组返回,显然仍然是串联的“文本文本”。因此,我使用LET() 将数组作为变量加载,并对所有元素进行一些字符串操作。

首先,我将所有字符串中最后出现的冒号替换为一个管道符号,然后我们 FIND() 并返回它的位置。现在我们有了可以使用LEFT() 提取正确子字符串的位置。使用 TEXTJOIN() 将结果数组重新连接在一起。

【讨论】:

  • +1,只是你在公式中输入了A7 而不是A2 的一件小事。我想是从错误的单元格复制的:)
  • 我收到一个错误。它似乎不适用于原始数据集,我拥有参考文献的真实标题。我是否需要为 FILTERXML 做任何事情,或者它应该自然地在 O365 工作簿上工作?
  • 它应该可以正常工作(除非您使用 Excel Online 或 Excel Mac)@Jas
  • 公式的 LET 位出现#NAME 错误。
  • 看起来LET 尚未普遍可用。 From Here 注意:这是几个测试版功能之一,目前仅对部分 Office 预览体验成员可用。在接下来的几个月中,我们将继续优化这些功能。准备就绪后,我们将向所有 Office 预览体验成员和 Microsoft 365 订阅者发布。
【解决方案2】:

如果您可以接受 VBA 解决方案,那么正则表达式非常适合此类问题。如果您的示例都如您所见:

我们使用正则表达式来查找子字符串

  • 以 PN 开头
  • 选择以下字符,直到我们以冒号结尾,后跟多个数字。
  • 如果后面有/,则查找下一个设置为冒号-多位数字模式。

要输入此用户定义函数 (UDF),&lt;alt-F11&gt; 将打开 Visual Basic 编辑器。 确保您的项目在 Project Explorer 窗口中突出显示。 然后,从顶部菜单中,选择 Insert/Module 并 将下面的代码粘贴到打开的窗口中。

要使用此用户定义函数 (UDF),请在某个单元格中输入类似 =extrPN(cell_Ref) 的公式。

Option Explicit
Function extrPN(S As String) As String
    Dim RE As Object, MC As Object, M As Object
    Const sPat As String = "PN[^:]+:\d+(?:/[^:]+:\d+)?"
    Dim sTemp As String
    
Set RE = CreateObject("vbscript.regexp")
With RE
    .Global = True
    .Pattern = sPat
    .ignorecase = False
    If .Test(S) = True Then
        Set MC = .Execute(S)
            For Each M In MC
                sTemp = sTemp & ", " & M
            Next M
            extrPN = Mid(sTemp, 3)
    Else: extrPN = "no match"
    End If
End With
End Function

正则表达式的解释

提取 PN

PN.*?:\d+(?:/[^:]+:\d+)?

选项:不区分大小写; ^$ 匹配换行符

使用RegexBuddy创建

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多