通过指定子字符串的第一个和最后一个来提取字符串中的子字符串

Posted

技术标签:

【中文标题】通过指定子字符串的第一个和最后一个来提取字符串中的子字符串【英文标题】:Extract sub-string's in a string by specifying the first and last of the sub string 【发布时间】:2015-06-19 16:36:20 【问题描述】:

我想知道是否有一种方法可以通过指定开始的几个字符和结束字符来从字符串中提取子字符串。

作为一个例子,我在工作簿的一个单元格中的问题底部有一个字符串,每个单元格都有一个类似的大字符串。我想将所有名称提取到一个数组中。

“c1-mc-”始终是名称的前缀。我希望我可以使用一个函数,我可以在其中指定每个以“c1-mc”开头并以 vbLf(enter) 结尾的子字符串,提取它们。 我认为 Instr() 和 Split() 可以提供帮助,但不确定如何继续。

"Str: 1/2/1
End  : 1/2/2
Name: cl-mc-23223322
Name: c1-mc-dddssda
Info: alot of detail
Name: c1-asa-dddssda
task: asdf
Name: c1-mc-xd132eds"



<the code which works>    
For Each rng1 In table1.DataBodyRange.Columns(8).Cells

MyString = rng1.Value
Do Until InStr(MyString, "c1-mc") = 0      
namestart = InStr(MyString, "c1-mc")
name = Mid(MyString, namestart)
nameend = InStr(name, vbLf) - 1
name = Left(name, nameend) 'this gives you a name
namestart = InStr(name, "c1-mc")
name = Mid(name, namestart)
nameend = InStr(name, " ") - 1
If (nameend = -1) Then
nameend = Len(name)
End If
name = Left(name, nameend) ' gives you name incase there are no next lines
MyString = Replace(MyString, name, "") 'this cuts the original string so it now starts where the name ended.
MsgBox name
i = i + 1
Loop
Next

【问题讨论】:

如果您经常这样做,您可能会发现正在使用的 VBA 中查看正则表达式。它允许根据标准对字符串进行各种切片和切块。这是an excellent post 的主题。 你给我看的字符串是这样的:“Str: 1/2/1End : 1/2/2Name: cl-mc-23223322Name: c1-mc-dddssdaInfo: alot of detailName: c1- asa-dddssdatask: asdfName: c1-mc-xd132eds" 字符串中没有“输入”。也许你的意思是 "Str: 1/2/1" & vbLF & "End : 1/2/2" & vbLF & "Name: cl-mc-23223322" & vbLF... @Byron 感谢您的参考。 【参考方案1】:

重新阅读您的问题后进行编辑,我认为我没有正确回答。请详细说明每个单元格中实际包含的内容,以及我们正在谈论的单元格数量(1?)。

字符串是字符的串联。在多行上写你的字符串并不意味着它实际上会改变。正如您所说,当您输入 chr(10) 或 vbLF 时会发生换行。我不确定您发布的字符串的哪一部分要提取。假设您要获取单元格的名称,并且该字符串保存在字符串变量 [mystring] 中:

Dim name as string
Dim namestart as integer
Dim nameend as integer

namestart = Instr(Mystring,  "c1-mc-" )
name  = Mid(Mystring, namestart + 1)
nameend = Instr(Mystring, vbLF)
name = Left(name, nameend)

现在 name 将包含您的字符串的名称。测试一下(我没有,你可能需要调整一些小事情),当你拥有它时,使用 for 循环遍历你的单元格并将名称添加到所需的数组中。

编辑 2: 由于您想提取单元格中名称的所有实例,因此我将其更改为:

Dim name as string
Dim namestart as integer
Dim nameend as integer
Dim namearray() as string
Dim i as integer

Do Until Instr(Mystring,  "c1-mc-" ) = 0 'will continue filling the array until Mystrign no longer has any names)
    namestart = Instr(Mystring,  "c1-mc-" )
    name  = Mid(Mystring, namestart + 1)
    nameend = Instr(Mystring, vbLF)
    name = Left(name, nameend) 'this gives you a name
    Mystring = Mid(Mystring, Instr(Mystring, name) ) 'this cuts the original string so it now starts where the name ended.
    namearray(i) = name
    i = i + 1
Loop

【讨论】:

我在问题中发布的字符串是描述事件的列的单元格值。同一字段可能有大约 4000-5000 行。在我的问题中,您可以看到名称 I.E "c1-mc-23223322" 等有 4 个实例。我想要一个数组中提取的所有名称。您在上面发布的代码,如何使用它在单元格值上运行多次? @Byron 谢谢,我也会研究正则表达式 我的编辑对您有帮助吗?现在它应该获取单元格中的所有名称(我还没有测试它,所以有可能将 +1 添加到字符位置,例如。使用 debug.print 找出添加了什么什么被剪掉了。) 我正在使用您提供的代码。有一点问题,但我能够提取作业名称。问题是它没有调整字符串的大小,我最终陷入了一个永无止境的循环。我会尽快发布代码,以便您查看。 我已经发布了代码。正如我之前所说,我进入了一个永无止境的循环,因为在删除第一个实例后字符串没有被调整大小。到目前为止,我正在处理的字符串有一个名称重复 4 次。会不会是这个原因?

以上是关于通过指定子字符串的第一个和最后一个来提取字符串中的子字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何获取一个字符串在某个字符串的位置

用C语言实现 原字符串中指定的子串的的查找与替换代码?注:一定要有用户自己输入指定子串的那个过程!

使用正则移除尖括号<>中的指定子字符串

//利用指针删除母串中的指定子串

指定子设备号创建字符设备

JAVA如何提取字符串中的第1个字符