1

The code below finds a string in a cell and extracts both the search word and the word that come before it.

When the search word is left as "(hello)" the code works but when I make it "(hello hey)" the code cannot find it. I assume its the white space in between "hello" and "hey" but I'm not sure how to make that change.

Dim c As Range, v As String, arr, x As Long, e
    Dim d As Range


    Set d = WorkSheets("Sheet1").Range("F1") '<<results start here

    For Each c In ActiveSheet.Range("D1:D10")
        v = Trim(c.Value)
        If Len(v) > 0 Then

            'normalize other separators to spaces
            v = Replace(v, vbLf, " ")
            'remove double spaces
            Do While InStr(v, "  ") > 0
                v = Replace(v, "  ", " ")
            Loop

            'split to array
            arr = Split(v, " ")
            For x = LBound(arr) To UBound(arr)
                e = arr(x)
                'see if array element is a word of interest
                If Not IsError(Application.Match(LCase(e), Array("(hello hey)"), 0)) Then
                    If x > LBound(arr) Then
                        d.Value = arr(x - 1) & " " & e 'prepend previous word
                    Else
                        d.Value = "??? " & e 'no previous word
                    End If
                    Set d = d.Offset(1, 0)
                End If
            Next x
        End If
   Next c
End Sub​

enter image description here

2
  • 2
    "(hello hey)" will never be matched, because it contains a space, and you're splitting all your cell values on space (and so no values in arr will contain spaces). Commented Aug 22, 2016 at 22:05
  • @TimWilliams Is there a way to treat the inside of a parentheses as a single vaule? Commented Aug 22, 2016 at 22:10

3 Answers 3

1

Instead of splitting by space, you can split by the search word and then by space:

Dim ws1 as WorkSheet, d As Range, c As Range
Dim v As String, arr() As String

Set ws1 = WorkSheets("Sheet1")
Set d = ws1.Range("F1") '<<results start here

For Each c In ws1.Range("D1:D10")
    v = WorksheetFunction.Trim(c.Value2) ' the Excel function TRIM() also replaces extra spaces between words to one space
    arr = Split(v, "(hello hey)")
    If UBound(arr) > 0 Then 
        v = arr(0)
        v = Replace(v, vbLf, " ")
        v = Trim(v)
        arr = Split(v) ' split by space to get the last word before the search word
        v = arr(UBound(arr)) ' the last word in arr

        d.Value2 = v
        Set d = d.Offset(1)
    End If
Next c
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the help!
1

One approach will be to just replace the first space with a different character (e.g ^) and leave the rest of the spaces intact. Now split the string on the basis of that newly introduced char.

So, Hi (hello hey) ---> Hi^(hello hey) ---> arr(0)= Hi and arr(1)= (hey hello)

Edit : Updated the code to handle multiple entries. Instead of replacing space, replace the ( and ). See the comments inside code for more details.

Sub test()

    Dim c As Range, v As String, arr, x As Long, e
    Dim d As Range

    Dim arr2


    Set d = Worksheets("Sheet1").Range("F1") '<<results start here

    For Each c In ActiveSheet.Range("D1:D10")
        v = Trim(c.Value)
        If Len(v) > 0 Then

            'normalize other separators to spaces
            v = Replace(v, vbLf, " ")
            'remove double spaces
            Do While InStr(v, "  ") > 0
                v = Replace(v, "  ", " ")
            Loop

            '/ Replace just the first space with ^
            'v = Replace(v, Space(1), "^", , 1) --- Commented as it wont work with multiple entries

            '/ Updated as per your edit in question.
            '/ Replace parenthesis with ^ appended.
            v = Replace(v, Space(1) & "(", "^(")
            v = Replace(v, ")", ")^")

            'split to array
            '/ Now split the array on ^, this way you get to keep the full string inside parenthesis
            arr = Split(v, "^")

            For x = LBound(arr) To UBound(arr)
                e = arr(x)
                'see if array element is a word of interest
                If Not IsError(Application.Match(LCase(e), Array("(hello hey)"), 0)) Then
                    If x > LBound(arr) Then
                        d.Value = arr(x - 1) & " " & e 'prepend previous word

                        '/ This part added as per your edit.
                        '/ It will bring back the word which precedes the search term.
                        arr2 = Split(StrReverse(Trim(arr(x - 1))), Space(1))
                        If UBound(arr2) > 0 Then
                            arr2(UBound(arr2)) = ""
                        End If
                        d.Value = Trim(StrReverse(Join(arr2, Space(1)))) & " " & e

                    Else
                        d.Value = "??? " & e 'no previous word
                    End If
                    Set d = d.Offset(1, 0)
                End If
            Next x
        End If
   Next c

End Sub

4 Comments

When there are sentences that are in the cell it cannot get to it but when its just the HI (hello hey). How can it account for indentations and sentences in the cell?
I'll add a screen shot
In the screen shot it shows that it pulls almost all the HI but the last one that is in the paragraph
see the updated answer. Works for me as per your updated screenshot.
1

I use Instr to find the phrase in the text then RegEx to find the last word before the phrase.

Function getWordBeforePhrase(text As String, phrase As String) As String

    Dim regex As Object, Match As Object
    Dim lEnd As Long

    lEnd = InStr(text, phrase) - 1

    If lEnd Then
        text = Left(text, lEnd)

        Set regex = CreateObject("VBScript.RegExp")
        With regex
            .Global = True
            .Pattern = "\w+"
            Set matches = regex.Execute(text)

        End With

        If matches.Count Then getWordBeforePhrase = matches(matches.Count - 1).Value

        Set regex = Nothing

    End If

End Function

3 Comments

No need for InStr. Just use a single regex. Something like: "\w+(?=\W*" & phrase & ")". Just need to be careful to escape the parentheses when entering phrase. e.g. "\(hello hey\)" or other special characters.
Thanks. I tried something similar but couldn't get it to work.
Thanks for the help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.