繁体   English   中英

具有数学属性的Excel VBA字符串转换

[英]Excel VBA String Conversion with Math Properties

我的好奇心激起了我的兴趣,使我感到难过。 我遇到一堆字符串,有些带有数学符号,有些只是字符的情况。 其中一些字符串很长,有些则不是,但是,我想在具有数学符号(特别是+,-)的任何字符串的完整字符串之后添加一个Chr(10),然后继续读取该字符串下一个数学符号,并在其前面插入一个Chr(10)。

最终结果应如下所示:

10+20+30+40 50+60+70+80 123a 123 123b 345 123c 123 123d 123 90+100+110+120 123 123 231 123

Converts to: 

10+20+30+40  
50+60+70+80 
123a 123 123b 345 123c 123 123d 123 
90+100+110+120 
123 123 231 123

在方程式没有空格的地方,普通字母(可以是数字和字母的混合)可以有空格,但是在找到数学符号时会分开。

我一直在网上寻找一些线索,我想我已经非常接近了。 似乎是split,merge或Right(),Left(),然后Len()函数才是答案。

 If Len(SearchString) = "+" Or Len(SearchString) = "-" Then
    SearchString = Left(SearchString, Chr(10))
 End If

但是,这不起作用。 我可能不太了解Len,Left和Right,但我很肯定SearchString是正确的做法。 还值得注意的是,我提供的If / End If语句确实起作用,它不会返回任何错误,但不会执行我想要的操作。

这是使用正则表达式的另一种方法。 我使用.Replace方法

Option Explicit
Sub splitter()
    Dim S As String, RE As Object
    Const spat As String = "((?:(?:\w+[+-])+)+\w+)(?=\s|$)|(?:^|\s)((?:\w+\s+)+\w+)(?=\s|$)"
    Dim sRes As Variant

S = "10+20+30+40 50+60+70+80 123a 123 123b 345 123c 123 123d 123 90+100+110+120 123 123 231 123"

Set RE = CreateObject("vbscript.regexp")
With RE
    .Global = True
    .MultiLine = True
    .Pattern = spat
    sRes = .Replace(S, vbLf & "$1$2")
    MsgBox sRes
End With

End Sub

如何应用此方法取决于您的数据设置。 查看原始数据并在某个地方吐出结果。

分离器

((?:(?:\w+[+-])+)+\w+)(?=\s|$)|(?:^|\s)((?:\w+\s+)+\w+)(?=\s|$)

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

$ 1 $ 2

RegexBuddy创建

大致来说,它可以满足您的需求。

sentence() = Split(10+20+30+40 50+60+70+80 123a 123 123b 345 123c 123 123d 123 90+100+110+120 123 123 231 123)

 For i = 0 To UBound(sentence)
  acu_str = sentence(i)
   If InStr(sentence(i), "+") = 0 And InStr(sentence(i), "-") = 0 Then
    Do While InStr(sentence(i + 1), "+") = 0 And InStr(sentence(i + 1), "-") = 0
    On Error GoTo ErrorHandling
     acu_str = acu_str + " " + sentence(i + 1)
    i = i + 1
    Loop
   ErrorHandling:
  End If
 Debug.Print acu_str & vbCr
 Next i

因此,这不是理想的方法,但使用正则表达式进行破坏。

Option Explicit
Public Sub TEST()
    Dim tests(), i As Long
    tests = Array("10+20+30+40 50+60+70+80 123a 123 123b 345 123c 123 123d 123 90+100+110+120 123 123 231 123")
    For i = LBound(tests) To UBound(tests)
        Debug.Print ReplaceString(tests(i))
    Next
End Sub

Public Function ReplaceString(ByVal inputString As String) As String
Dim matches As Object, match As Object
  With CreateObject("VBScript.RegExp")
            .Global = True
            .MultiLine = True
            .Pattern = "(\w+\+|\-)+(\w)+"
            If .TEST(inputString) Then
              Set matches = .Execute(inputString)
              For Each match In matches
                  inputString = Replace$(Replace$(inputString, Chr$(32) & match, Chr$(10) & match), match & Chr$(32), match & Chr$(10))
              Next
              ReplaceString = Trim$(inputString)
            Else
              ReplaceString = inputString
            End If
  End With
End Function

第一捕获组(\\w+\\+|\\-)+

\\+量词-匹配一次和无限次,尽可能多地匹配,并根据需要返回(贪婪)

第一替代\\w+\\+

\\w+匹配任何单词字符(等于[a-zA-Z0-9_]

\\+量词-匹配一次和无限次,尽可能多地匹配,并根据需要返回(贪婪)

\\+逐字匹配字符+ (区分大小写)

第二个替代项\\- \\-匹配字符-按字面值(区分大小写)

第二捕获组(\\w)+

\\+量词-匹配一次和无限次,尽可能多地匹配,并根据需要返回(贪婪)

\\w匹配任何单词字符(等于[a-zA-Z0-9_ ])

在这里尝试

感谢@RonRosenfeld帮助我改善正则表达式。

InStr和InStrRev应该能够处理拆分。

Option Explicit    

Function splitString(str As String)

    Dim a As Long, b As Long

    a = InStr(1, str, Chr(32))
    b = InStr(1, str, Chr(43))

    Do While a > 0 And b > 0

        If b > a Then
            a = InStrRev(str, Chr(32), b)
        End If

        Mid(str, a, 1) = Chr(10)

        b = InStr(a, str, Chr(43))
        a = InStr(a, str, Chr(32))

    Loop

    splitString = str

End Function

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM