如何在文本字符串中提取文本

Bra*_*don 16 excel vba worksheet-function excel-vba excel-formula

我有一个简单的问题,我希望在不使用VBA的情况下解决,但如果这是解决它的唯一方法,那就这样吧.

我有一个包含多行的文件(所有一列).每行的数据看起来像这样:

1 7.82E-13> gi | 297848936 | ref | XP_00 | 4-氢氧化物gi | 297338191 | gb | 23343 | randomrandom

2 5.09E-09> gi | 168010496 | ref | xp_00 | 2 - 丙酮酸盐

等等...

我想要的是一些方法来提取以"gi |"开头的数字串 并以"|"结束.对于某些行,这可能意味着多达5个gi数字,而对于其他行,它只是一个.

我希望输出看起来像是这样的:

297848936,297338191

168010496

等等...

aev*_*nko 45

这是一个使用正则表达式对象的非常灵活的VBA答案.该函数所做的是提取它找到的每个子组匹配(括号内的东西),用你想要的任何字符串分隔(默认为",").你可以在这里找到关于正则表达式的信息:http://www.regular-expressions.info/

假设第一个字符串在A1中,你会这样称呼它:

=RegexExtract(A1,"gi[|](\d+)[|]")
Run Code Online (Sandbox Code Playgroud)

因为这会查找"gi |"的所有发生 然后是一系列数字,然后是另一个"|",对于你问题的第一行,这会给你这个结果:

297848936, 297338191
Run Code Online (Sandbox Code Playgroud)

只需在列中运行,您就完成了!

Function RegexExtract(ByVal text As String, _
                      ByVal extract_what As String, _
                      Optional separator As String = ", ") As String

Dim allMatches As Object
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
Dim i As Long, j As Long
Dim result As String

RE.pattern = extract_what
RE.Global = True
Set allMatches = RE.Execute(text)

For i = 0 To allMatches.count - 1
    For j = 0 To allMatches.Item(i).submatches.count - 1
        result = result & (separator & allMatches.Item(i).submatches.Item(j))
    Next
Next

If Len(result) <> 0 Then
    result = Right$(result, Len(result) - Len(separator))
End If

RegexExtract = result

End Function
Run Code Online (Sandbox Code Playgroud)

  • 非常欢迎你!至于为什么我要花时间:我这样做是因为其他人这样做.我认为这更像是'付出前进'的事情.我帮助别人,因为有一天,他们会帮助我一些代码,我帮助的人会帮助别人等等:) (19认同)
  • 哦,男人,这很美.绝对棒极了.说真的,你为什么这样做?它是如此有用,但我只是好奇为什么人们为这样的事情花时间?对你们所有人来说,这都是非常慈善的. (7认同)
  • 正则表达式是一个很好的方式.+1对于我自己,我回答问题,因为它很有趣,也是学习/练习的好方法.此外,就像Issun所说,多年来我在新闻组和其他论坛上得到了慷慨和非常有才华的人们的惊人帮助. (2认同)

Zel*_*ada 6

这是(假设数据在A列)

=VALUE(LEFT(RIGHT(A1,LEN(A1) - FIND("gi|",A1) - 2),
FIND("|",RIGHT(A1,LEN(A1) - FIND("gi|",A1) - 2)) -1 ))
Run Code Online (Sandbox Code Playgroud)

不是最好的公式,但它可以提取数字.

我刚注意到,因为每行有两个值,输出用逗号分隔.您需要检查是否存在第二个匹配,第三个匹配等,以使其适用于每个单元格的多个数字.

在参考您的确切示例(假设每个单元格最多2个值)时,以下代码将起作用:

=IF(ISNUMBER(FIND("gi|",$A1,FIND("gi|", $A1)+1)),CONCATENATE(LEFT(RIGHT($A1,LEN($A1)
- FIND("gi|",$A1) - 2),FIND("|",RIGHT($A1,LEN($A1) - FIND("gi|",$A1) - 2)) -1 ), 
", ",LEFT(RIGHT($A1,LEN($A1) - FIND("gi|",$A1,FIND("gi|", $A1)+1) 
- 2),FIND("|",RIGHT($A1,LEN($A1) - FIND("gi|",$A1,FIND("gi|", $A1)+1) - 2)) 
-1 )),LEFT(RIGHT($A1,LEN($A1) - FIND("gi|",$A1) - 2),
FIND("|",RIGHT($A1,LEN($A1) - FIND("gi|",$A1) - 2)) -1 ))
Run Code Online (Sandbox Code Playgroud)

丑陋怎么样?VBA解决方案可能对您更好,但我会留在这里为您服务.

要获得最多5个数字,请研究模式并在公式中手动递归.IT会变长!