如何提取文本string中的文本

我有一个简单的问题,我希望解决而不使用VBA,但如果这是唯一可以解决的方法,那就这样吧。

我有一个多行(全部一列)的文件。 每行的数据看起来像这样:

1 7.82E-13> gi | 297848936 | ref | XP_00 | 4-hydroxide gi | 297338191 | gb | 23343 | randomrandom

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

等等…

我想要的是提取以“gi |”开头的数字串的方法 并以“|”结尾。 对于某些行来说,这可能意味着多达5个gi数字,对于其他数字则只能是一个。

我希望输出结果如下所示:

297848936,297338191

168010496

等等…

这是一个非常灵活的使用正则expression式对象的VBA答案。 函数做的是提取它find的每一个子组匹配(在括号内的东西),由你想要的任何string分隔(默认是“,”)。 你可以在这里find有关正则expression式的信息: http : //www.regular-expressions.info/

你会这样调用它,假设第一个string在A1:

=RegexExtract(A1,"gi[|](\d+)[|]") 

由于这看起来是所有的“gi |” 然后是一系列数字,然后是另一个“|”,对于你的问题的第一行,这会给你这个结果:

 297848936, 297338191 

只要在列中运行,你就完成了!

 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 

在这里(假设数据在列A中)

 =VALUE(LEFT(RIGHT(A1,LEN(A1) - FIND("gi|",A1) - 2), FIND("|",RIGHT(A1,LEN(A1) - FIND("gi|",A1) - 2)) -1 )) 

不是最好的公式,但它会提取数字。

我只是注意到,因为你有每行两个值与输出分隔逗号。 你将需要检查是否有第二个匹配,第三个匹配等,使其工作在每个单元格的多个数字。

参考你的确切的例子(假设每个单元最多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 )) 

那么丑陋呢? 一个VBA解决scheme可能会更好,但我会留在这里给你。

为了达到5位数,好的,在公式中学习模式和手动recursion。 IT会变长!

我可能会首先在|上分割数据 使用转换文本到列向导的分隔符。 在“ 数据”选项卡,“ 数据工具”组中的Excel 2007中,然后select“ 文本到列” 。 指定其他:| 作为分隔符。

从你发布的样本数据看起来像这样做后,数字将全部在同一列,所以你可以删除你不想要的列。

正如其他人提出了没有VBA的解决scheme…我将介绍一个使用的。 现在,你的电话是使用它还是不使用。

只是看到@Issun用正则expression式提供了解决scheme,非常好! 无论哪种方式,只会使用“简单”的VBA来提出一个“适度”的解决scheme。

 Option Explicit Option Base 0 Sub findGi() Dim oCell As Excel.Range Set oCell = Sheets(1).Range("A1") 'Loops through every row until empty cell While Not oCell.Value = "" oCell.Offset(0, 1).Value2 = GetGi(oCell.Value) Set oCell = oCell.Offset(1, 0) Wend End Sub Private Function GetGi(ByVal sValue As String) As String Dim sResult As String Dim vArray As Variant Dim vItem As Variant Dim iCount As Integer vArray = Split(sValue, "|") iCount = 0 'Loops through the array... For Each vItem In vArray 'Searches for the 'Gi' factor... If vItem Like "*gi" And UBound(vArray) > iCount + 1 Then 'Concatenates the results... sResult = sResult & vArray(iCount + 1) & "," End If iCount = iCount + 1 Next vItem 'And removes trail comma If Len(sResult) > 0 Then sResult = Left(sResult, Len(sResult) - 1) End If GetGi = sResult End Function