Split Text based on delimiter

Pete2020

Board Regular
Joined
Apr 25, 2020
Messages
68
Office Version
  1. 2016
Platform
  1. Windows
I am looking to create a multiple combination of a sentence based on Curly brackets and "|" Separators in the text. We usually call this as nested spintax .
  • Every Curly bracket contains a word separator with "|" delimiter
  • The Output is shown in the Column F for every combination of words using curly brackets and "|" delimiter

Column A is the Primary Key ID and based on it The column B should generate multiple combinations and Out put should be generated in column E and F

These are the common patterns of my data.

Book1
ABCDEF
1IDTextIDText Output
2SP-001{Nice|Cool|Beautiful} photo.SP-001Nice photo.
3SP-002{Hello|Hi} {World|People}!SP-001Cool photo.
4SP-003{hello there my {friend|dude|buddy|pal}SP-001Beautiful photo.
5SP-004Very {interesting|beautiful} woman {image|photo|picture}SP-002Hello World!
6SP-005This is nested {{very|quite} deeply|deep}.SP-002Hi People!
7SP-002Hello People!
8SP-002Hi World!
9SP-003hello there my friend
10SP-003hello there my dude
11SP-003hello there my buddy
12SP-003hello there my pal
13SP-004Very interesting woman image
14SP-004Very interesting woman photo
15SP-004Very interesting woman picture
16SP-004Very beautiful woman image
17SP-004Very beautiful woman photo
18SP-004Very beautiful woman picture
19SP-005This is nested very deeply.
20SP-005This is nested quite deeply.
21SP-005This is nested deep.
22SP-005This is nested deeply.
Sheet1
 

Excel Facts

Copy PDF to Excel
Select data in PDF. Paste to Microsoft Word. Copy from Word and paste to Excel.
I'm curious about your nested notation.
"{very|quite} deeply" >>> "very deeply" and "quite deeply"

I would think that
"nested {{very|quite} deeply|deep}" >>> "nested {very deeply|quite deeply|deep}"
>>>
"nested very deeply" and "nested quite deeply" and "nested deep}

Yet your result column shows "nested very deeply", "nested quite deeply", "nested deep", "nested deeply"

To get the last string wouldn't the top string need to be "nested {very|quite|} deeply|deep"
(note the | immediately after "quite")
 
Upvote 0
You are Right.
I'm curious about your nested notation.
"{very|quite} deeply" >>> "very deeply" and "quite deeply"

I would think that
"nested {{very|quite} deeply|deep}" >>> "nested {very deeply|quite deeply|deep}"
>>>
"nested very deeply" and "nested quite deeply" and "nested deep}

Yet your result column shows "nested very deeply", "nested quite deeply", "nested deep", "nested deeply"

To get the last string wouldn't the top string need to be "nested {very|quite|} deeply|deep"
(note the | immediately after "quite")


Actually the nested Notation is correct.I missed to add the 2 more results in out put

This is nested {{very|quite} deeply|deep}.

Output to be added is

This is nested very deep
This is nested quite deep
 
Upvote 0
i updated my output

Output to be added is

This is nested very deep
This is nested quite deep
 
Upvote 0
I think the function Interpret might do what you want.
It takes a string and returns an array of all the resulting strings.
The return array is a row-wise array

Select D2:D10 and enter the array formula =TRANSPOSE(Interpret(B2)) (entered with Ctrl+Shift+Enter)

regarding
"This is nested {{very|quite} deeply|deep}"

That is "This is nested" followed by two options "{very|quite} deeply" and "deep"
accounting for all the subopions you get

"very deeply"
"quite deeply"
"deep"

If you want "very deeply", "quite deeply", "very deep", "quite deep"

the string would be "This is nested {{very|quite} {deeply|deep}}"
 
Upvote 0
Sorry about the last post. I discovered mid-post that the solution that I thought I had wasn't quite.

But to get back to the notation issue, the use of "" as one of the options can be gotten with strings like

"a{b1|b2|}c" (note the pipe after the 2)
which should produce

ab1c
ab2c
ac
 
Upvote 0
Please Ignore last pipe after 2 as there no text and it is closed by brackets.

The out put is

ac
 
Upvote 0
A well developed system should allow for vbNullString as an option.
Leaving that last pipe out is the user's resposibility. The coder should set up their structure for maximum flexibility and let the user follow conventions.
(Pipe's outside of braces are one of the problems.) "a|{x|y}" goes to "a|x" and "a|y"
 
Upvote 0
O.K. I think I've got it.
The function Interpret will take a string and return a (0-based, 1 dimensional) array of the combinations that that string produces.

Interpret("You are {beautiful|pretty}.") = Array("You are beautiful.", "You are pretty.")

It also takes sub brackets


While it doesn't completely answer the OP, it does the heavy lifting.
Let me know if this does what you want and if you need help building the multi-input macro requested in the OP
VBA Code:
Const strLeft As String = "{"
Const strRight As String = "}"
Const strPipe As String = "|"

Function Interpret(ByVal aString As String, Optional PipeMode As Boolean) As Variant
    Dim i As Long
    Dim Result() As String, Pointer As Long
    Dim Elements As Variant, oneElement As Variant, oneString As Variant
    Dim ElementResults As Variant, oneResult As Variant, elementCount As Long
    Dim ElementIndexes() As Long
    Dim thisResult As Variant, thisSubString As String
    Dim IndexPointer As Long, IndexFlag As Boolean
    Dim temp
    ReDim Result(0 To 0): Pointer = -1
   
    If PipeMode Then
        Elements = ParseString(aString, "|")
        For Each oneElement In Elements
            For Each oneResult In Interpret(oneElement)
                Pointer = Pointer + 1
                If UBound(Result) < Pointer Then ReDim Preserve Result(0 To 2 * Pointer)
                Result(Pointer) = oneResult
            Next oneResult
        Next oneElement
    Else
        Elements = ParseString(aString)
        If (UBound(Elements) = 0) And aString Like ("{*}") Then
            temp = Mid(aString, 2, Len(aString) - 2)
            Result = Interpret(temp, True)
            Pointer = UBound(Result)
        ElseIf aString Like "*{*}*" Then
            elementCount = UBound(Elements)
            ReDim ElementResults(0 To elementCount)
            For i = 0 To elementCount
                ElementResults(i) = Interpret(CStr(Elements(i)))
            Next i
           
            ReDim ElementIndexes(0 To elementCount)
           
            Do
                Pointer = Pointer + 1
                If UBound(Result) < Pointer Then ReDim Preserve Result(0 To 2 * Pointer)
                For i = 0 To elementCount
                    thisResult = ElementResults(i)
                    thisSubString = thisResult(ElementIndexes(i))
                    Result(Pointer) = Result(Pointer) & thisSubString
                Next i
               
                Rem incriment indexees
                IndexPointer = elementCount
                Do
                    IndexFlag = False
                    ElementIndexes(IndexPointer) = ElementIndexes(IndexPointer) + 1
                    If ElementIndexes(IndexPointer) > UBound(ElementResults(IndexPointer)) Then
                       ElementIndexes(IndexPointer) = 0
                        IndexPointer = IndexPointer - 1
                        IndexFlag = True
                        If IndexPointer < 0 Then Exit Do
                    End If
                Loop While IndexFlag
                IndexFlag = (IndexPointer < 0)
           
            Loop Until IndexFlag
        Else
            Rem aString is single string
            Pointer = 0
            Result(Pointer) = aString
        End If
    End If
    ReDim Preserve Result(0 To Pointer)
   
    Interpret = Result
End Function

Function ParseString(aString As String, Optional onDelimiter As String = "{") As Variant
    Dim BracketCount As Long
    Dim thisChr As String
    Dim i As Long
    Dim Result() As String, Pointer As Long
   
    ReDim Result(0 To Len(aString))
    Pointer = 0
   
    If onDelimiter = strLeft Then
        For i = 1 To Len(aString)
            thisChr = Mid(aString, i, 1)
            If thisChr = strLeft Then
                If 0 = BracketCount Then
                    Rem end previous
                    Pointer = Pointer + Sgn(Len(Result(Pointer)))
                End If
                Result(Pointer) = Result(Pointer) & thisChr
                BracketCount = BracketCount + 1
            ElseIf thisChr = strRight Then
                BracketCount = BracketCount - 1
                Result(Pointer) = Result(Pointer) & thisChr
                 If 0 = BracketCount Then
                    Rem end previous
                    Pointer = Pointer + Sgn(Len(Result(Pointer)))
                End If
            Else
                Result(Pointer) = Result(Pointer) & thisChr
            End If
           
        Next i
        If Result(Pointer) = vbNullString Then Pointer = Pointer - 1
       
        If Pointer < 0 Then Pointer = 0
        ReDim Preserve Result(0 To Pointer)
    Else
        For i = 1 To Len(aString)
            thisChr = Mid(aString, i, 1)
            If thisChr = strPipe And BracketCount = 0 Then
                Pointer = Pointer + 1
            ElseIf thisChr = strLeft Then
                BracketCount = BracketCount + 1
                Result(Pointer) = Result(Pointer) & thisChr
            ElseIf thisChr = strRight Then
                BracketCount = BracketCount - 1
                Result(Pointer) = Result(Pointer) & thisChr
            Else
                Result(Pointer) = Result(Pointer) & thisChr
            End If
        Next i
        ReDim Preserve Result(0 To Pointer)
    End If
    ParseString = Result
End Function
 
Last edited:
Upvote 0
And to return to the {deeply|deep}

Interpret("This is nested {{very|quite} {deeply|deep}}.") returns
1589336291090.png


Interpret("This is nested {{very|quite} deeply|deep}.") returns
1589336358569.png


Interpret("This is nested {{very|quite|} {deeply|deep}}.") returns
1589336420973.png
 

Attachments

  • 1589336233668.png
    1589336233668.png
    2.2 KB · Views: 6
Upvote 0

Forum statistics

Threads
1,224,823
Messages
6,181,177
Members
453,021
Latest member
Justyna P

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top