How do I implement text spinning in vb.net!?

MarketerX

Regular Member
Joined
Mar 7, 2010
Messages
404
Reaction score
125
Hey folks...I have a textbox control that I want the user to be able to input the common spintax {word1|word2|word3} ect and one of my methods will be able to correctly spin it and use it's value...

I know someone has implemented this within their apps, can someone please help???? It will benefit everyone here when I release my bot which would benefit from this feature..

:D
 
This is the code I use I found it somewhere a while ago as I was too bored to write my own ;)

Code:
Function Spin(ByRef value As String) As String
        ' Invoke the Regex.Replace function.
        Return Regex.Replace(value, _
        "{.*?}", _
        New MatchEvaluator(AddressOf SpinEvaluator))
    End Function

    Function SpinEvaluator(ByVal match As Match) As String
        ' Get string from match.
        Dim v As String = match.ToString()

        If v.Contains("{") Then
            Dim x() As String = v.Split("|")

            Dim kwd As String = x(GetRandom(0, x.Length)).Replace("{", "").Replace("}", "")

            Return kwd
        Else
            Return v
        End If
    End Function
 
Nice function, I grabbed one from somewhere without the use of Regex:

Code:
Function Tokenize(ByVal SourceString As String) As String
        Dim ReturnString As New StringBuilder
        Dim I As Integer = 0
        Randomize()
        Do While I < SourceString.Length
            Dim c As Char = SourceString.Chars(I)
            Select Case c
                Case ("{"c)
                    ReturnString.Append(Tokenize(SourceString.Substring(I + 1)))
                    Exit Do
                Case ("}"c)
                    Dim Options As String() = ReturnString.ToString().Split("|"c)
                    ReturnString = New StringBuilder
                    ReturnString.Append(Options(CType(Math.Floor(Rnd() * CType(Options.Length, Single)), Integer)))
                    If I < SourceString.Length - 1 Then
                        SourceString = SourceString.Substring(I + 1)
                        I = -1
                    Else
                        SourceString = ""
                    End If
                Case Else
                    ReturnString.Append(c)
            End Select
            I += 1
        Loop
        Return ReturnString.ToString()
    End Function
 
Thanks alot guys, you saved me a ton of testing/probably frustration from trying to find a solution on my own.

Cheers, this will be so helpful for pretty much any blackhat bot ;)
 
I just realized that I haven't defined the GetRandom function. The commone GetRandom function that is around the web is not great when it comes to spinning this is the one I use:

Code:
    Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer
        Randomize()
        Return Int(Max * Rnd() + Min)

    End Function
 
Here's the same one gimme has but with comments so you can understand what's going on - I forget who coded it but it was a BHW member.

Code:
    Public Function Spin(ByVal SourceString As String) As String
        '
        '    Create a temp return info
        '
        Dim ReturnString As New System.Text.StringBuilder
        '
        '    The loop position in the source string
        '
        Dim I As Integer = 0
        '
        '    Sart a new random sequence
        '
        Randomize()
        '
        '    While there is something in the source
        '
        Do While I < SourceString.Length
            '
            '    Get the char to process
            '
            Dim c As Char = SourceString.Chars(I)
            '
            '    Depending on the char
            '
            Select Case c
                Case "{"c
                    '
                    '    This is an opening so must start a deeper level
                    '
                    ReturnString.Append(Spin(SourceString.Substring(I + 1)))
                    Exit Do
                Case "}"c
                    '
                    '    This is a closing one.
                    '--------------------------------------------------------
                    '
                    '    calculate the options using the | separator
                    '
                    Dim Options As String() = ReturnString.ToString.Split("|"c)
                    '
                    '    Clear the return string to get an option. 
                    '
                    ReturnString = New System.Text.StringBuilder
                    '
                    '    Get the option
                    '
                    ReturnString.Append(Options(CType(Math.Floor(Rnd() * CType(Options.Length, Single)), Integer)))
                    '
                    '    Get hte rest of the string past the closing bracket
                    '
                    If I < SourceString.Length - 1 Then
                        '
                        '    Disregard all the source before the ending bracket and reset the pointer
                        '
                        SourceString = SourceString.Substring(I + 1)
                        I = -1
                    Else
                        '
                        '    If this is the last char, then nothing more to analyze
                        '
                        SourceString = ""
                    End If
                Case Else
                    '
                    '    this is a normal char
                    '
                    ReturnString.Append(c)
            End Select
            '
            '    Go for the next char
            '
            I += 1
        Loop
        '
        '    Return the valid string
        '
        Return ReturnString.ToString

    End Function
 
Code:
Imports System.Text.RegularExpressions

Public Class Form1

    Public rand As New Random() ' random function needs to be declared as a member to work as expected

    Public Function GetRandomItem(ByVal m As Match) As String
        ' split on the pipe symbol and get the random index based on the resulting array length
        Dim items As String() = m.Groups("Items").Value.Split("|")
        Dim randomIndex As Integer = rand.Next(0, items.Length)
        Return items(randomIndex)
    End Function


    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles spin2.Click
        Dim input As String
        input = RichTextBox1.Text
        Dim pattern As String = "{(?<Items>(?:.+?\|[^}]+))}"
        ' Using Replace with a MatchEvaluator
        Dim result As String = Regex.Replace(input, pattern, AddressOf GetRandomItem)
        RichTextBox2.Text = (result)

    End Sub
End Class
 
Here is is function for nested spinning. Can be a bit slow on LARGE texts but works fine.

HTML:
Private Function Spin(ByVal Data As String) As String
Try
 If Data.length = 0 Then Return ""
 Dim pattern As String = "{[^{}]*}"
 Dim m As Match = Regex.Match(Data, pattern)
 Dim seg As String = ""
 Dim val() As String = Nothing
 Dim rnd As New Random
 
 While m.Success
                seg = Data.Substring(m.Index + 1, m.Length - 2)
                val = Split(seg, "|")
                Data = Data.Substring(0, m.Index) & val(rnd.Next(val.Length)) & Data.Substring(m.Index + m.Length)
                m = Regex.Match(Data, pattern)
 End While
        pattern =  nothing
        m = Nothing
        seg = Nothing
        val = Nothing
        rnd = Nothing

Catch ex As Exception
'possible errors here are memory related.       
End Try
Return Data
End Function
 
simple way is to split token and replace string with token and do it recursively...

I have done that in C# and works good.
 
Back
Top