Suppose I need to add the ASCII version of each character in the word "hello" to "hi" so that the result would be something like this: (h+h = )(e+i = )(l+h = )(l+i = )(o+h = ) etc how would I go about looping the "hi" string?
I have already managed to loop the "hello" string, but not quite sure how to do the second without getting (h+h = )(h+i = )(e+h = )(e+i = ) etc.
Thanks!
You can use the Mod opreator to make the index start over. Example:
Dim str1 as String = "hello"
Dim str2 as String = "hi"
' This gets the length of the longest string
Dim longest = Math.Max(str1.Length, str2.Length)
' This loops though all characters
' The Mod operator makes the index wrap over for the shorter string
For i As Integer = 0 To longest - 1
Console.Write(str1(i Mod str1.Length))
Console.WriteLine(str2(i Mod str2.Length))
Next
Output:
hh
ei
lh
li
oh
Related
I have Textboxes Lines:
{ LstScan = 1,100, DrwR2 = 0000000043 }
{ LstScan = 2,200, DrwR2 = 0000000041 }
{ LstScan = 3,300, DrwR2 = 0000000037 }
I should display:
1,100
2,200
3,300
this is a code that I can't bring to a working stage.
Dim data As String = TextBox1.Lines(0)
' Part 1: get the index of a separator with IndexOf.
Dim separator As String = "{ LstScan ="
Dim separatorIndex = data.IndexOf(separator)
' Part 2: see if separator exists.
' ... Get the following part with Substring.
If separatorIndex >= 0 Then
Dim value As String = data.Substring(separatorIndex + separator.Length)
TextBox2.AppendText(vbCrLf & value)
End If
Display as follows:
1,100, DrwR2 = 0000000043 }
This should work:
Function ParseLine(input As String) As String
Const startKey As String = "LstScan = "
Const stopKey As String = ", "
Dim startIndex As String = input.IndexOf(startKey)
Dim length As String = input.IndexOf(stopKey) - startIndex
Return input.SubString(startIndex, length)
End Function
TextBox2.Text = String.Join(vbCrLf, TextBox1.Lines.Select(AddressOf ParseLine))
If I wanted, I could turn that entire thing into a single (messy) line... but this is more readable. If I'm not confident every line in the textbox will match that format, I can also insert a Where() just before the Select().
Your problem is you're using the version of substring that takes from the start index to the end of the string:
"hello world".Substring(3) 'take from 4th character to end of string
lo world
Use the version of substring that takes another number for the length to cut:
"hello world".Substring(3, 5) 'take 5 chars starting from 4th char
lo wo
If your string will vary in length that needs extracting you'll have to run another search (for example, searching for the first occurrence of , after the start character, and subtracting the start index from the newly found index)
Actually, I'd probably use Split for this, because it's clean and easy to read:
Dim data As String = TextBox1.Lines(0)
Dim arr = data.Split()
Dim thing = arr(3)
thing now contains 1,100, and you can use TrimEnd(","c) to remove the final comma
thing = thing.TrimEnd(","c)
You can reduce it to a one-liner:
TextBox1.Lines(0).Split()(3).TrimEnd(","c)
I have a user-defined function in an Excel VBA module. Let's say it's:
Function MyFunc( val1 as Double, val2 as int, val3 as int ) as Double
MyFunc = val1 * val2 + val3
End Function
I also have another Function MyEval:
Function MyEval( formula as string )
MyEval = Evaluate( formula )
End Function
In a worksheet, the cell B1 contains the following string:
"blah blah blah "&MyFunc(VAL,2,0)&" foobar "&MyFunc(VAL,6,5)&" do re mi"
Note that the quotes are part of the string, not just denoting that it is a string. In second cell, I have the following:
=MyEval(SUBSTITUTE(B1,"VAL",8))
In general this works. In the above case I would get, as expected, the string:
blah blah blah 16 foobar 53 do re mi
In some cases, however, I would get #VALUE!. When I examined those examples that failed, I would find that removing different parts would allow the string to evaluate, but that no specific part caused it to fail, i.e., just the first half works, just the second half works, and just the middle part works.
Thinking that it might be a length issue (strings are up to 200 characters), I wrote a new evaluation function, where I break the string into parts on the concatenate symbol (&), evaluate each part separately, and then concatenate the results together:
Function MyEval2(formula As String)
If Len(formula) = 0 Then
Eval2 = ""
Else
Dim parts() As String
parts = Split(formula, "&")
Dim result As String
result = ""
Dim index As Integer
Dim part As String
For index = LBound(parts) To UBound(parts)
part = parts(index)
If (Left(part, 1) = """") And (Right(part, 1) = """") Then
part = Left(part, Len(part) - 1)
part = Right(part, Len(part) - 1)
result = result & part
Else
Dim val As Variant
val = Evaluate(part)
result = result & val
End If
Next index
Eval2 = result
End If
End Function
In this case, sometimes when the variable 'part' was, for example, the string
MyFunc(8,6,5)
the line
val = Evaluate(part)
resulted in 'val' being the string
MyFunc(8,6,5)
instead of the value 53.
Note: I have extensively re-written this to make it clearer.
I'm working on extracting twitter/facebook style mentions from a textbox.
So far, here's my code:
Dim a As String = TextBox1.Text + " "
Dim b As Char() = a.ToCharArray
Dim c As String
Dim l As Integer = TextBox1.Text.Length
Dim temp As Integer = 0
Dim nex As Integer = a.IndexOf(" ")
For i = 0 To l - 1
If b(i) = "#" Then
temp = 1
ElseIf temp = 1 Then
temp = 2
End If
If temp = 2 Then
c = a.Substring(i, nex).Trim() 'nex needs be replaced with next space on 2nd or nth loop
MsgBox(c)
temp = 0
nex = a.IndexOf(" ") + nex
End If
Next
Now this works great if the entered text is- #one #twwo #three. (If
the next strings are greater in length.) But doesn't work elsewhere.
Also, there is probably going to be content between two #mentions so I'm not willing to change the b(i).
I'm sure there's a much more efficient way to do this.
Thanks!!
This is a job for regex. The pattern #\w+ should do nicely.
For Each m As Match In Regex.Matches("#testing this is a #test", "#\w+")
Console.WriteLine(m.Value)
Next
Will print out #testing and #test.
This pattern basically means "Find everything that starts with an '#' followed by one or more 'word characters'."
Regex is a very powerful tool for searching strings, you can read more about it on MSDN.
I need to get a certain character from a long string line, that occurs more than once. This is what the string looks like:
<Press T><Press Left><Press A><Press C><Press P><Press U><Press G><Press P><Press NumPad7><Press NumPad7><Press A>
I need to loop through each set of <>'s and get the info that is after each occurrence of the word Press. So in this case I would need the info T, Left, A, C, P, etc
I think this pure String-method approach is the most efficient, but it requires the format to be strict:
Dim text = "<Press T><Press Left><Press A><Press C><Press P><Press U><Press G><Press P><Press NumPad7><Press NumPad7><Press A>"
Dim allKeys As New List(Of String)
Dim pattern = "Press "
Dim index = text.IndexOf(pattern)
While index >= 0
index += pattern.Length
Dim endIndex = text.IndexOf(">", index)
If endIndex >= 0 Then
Dim nextKey = text.Substring(index, endIndex - index)
allKeys.Add(nextKey)
index = text.IndexOf(pattern, endIndex + 1)
Else
Exit While
End If
End While
Console.Write(String.Join(", ", allKeys))
Output: T, Left, A, C, P, U, G, P, NumPad7, NumPad7, A
Here is the Regex that returns all matches, you find the "key" that was pressed in the second group:
pattern = "<Press ([^>]+)>"
Dim regex = New Regex( pattern, RegexOptions.Compiled And RegexOptions.IgnoreCase)
For Each match As Match In regex.Matches(text)
Console.WriteLine(match.Groups(1))
Next
Assuming it's the same format all the time you can do this in one line. Regex would be better if there's a chance the format would be different (e.g. random number of whitespaces etc..)
Dim myString As String = "<Press T><Press Left><Press A><Press C><Press P><Press U><Press G><Press P><Press NumPad7><Press NumPad7><Press A>"
Dim character As String() = myString.Split(New String() {"<Press ", ">"}, StringSplitOptions.RemoveEmptyEntries)
RegEx, short for regular expressions, is an easy way to parse strings. This site Provides good information on using RegEx in .NET. It's how I learned. The site also provides good info on RegEx in general if you are not familiar.
Edit: RegEx expressions can be complicated to create. A great tool to help you out with that is Expresso. It'll help you create and test very complicated expressions with a minimal of fuss.
Dim s As String = "<Press T><Press Left><Press A><Press C><Press P><Press U><Press G><Press P><Press NumPad7><Press NumPad7><Press A>"
Dim ss() As String = s.Replace("<Press ", "").Split(">"c)
For i as integer = 0 to ss.count - 2
Debug.Print(ss(i))
Next
Output:
T
Left
A
C
P
U
G
P
NumPad7
NumPad7
A
Note that the array ss is one longer than the number of key presses due to the final ">" being treated as another separator by .split, you could always remove the final ">"
I have a string (for example: "Hello there. My name is John. I work very hard. Hello there!") and I am trying to find the number of occurrences of the string "hello there". So far, this is the code I have:
Dim input as String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase as String = "hello there"
Dim Occurrences As Integer = 0
If input.toLower.Contains(phrase) = True Then
Occurrences = input.Split(phrase).Length
'REM: Do stuff
End If
Unfortunately, what this line of code seems to do is split the string every time it sees the first letter of phrase, in this case, h. So instead of the result Occurrences = 2 that I would hope for, I actually get a much larger number. I know that counting the number of splits in a string is a horrible way to go about doing this, even if I did get the correct answer, so could someone please help me out and provide some assistance?
Yet another idea:
Dim input As String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase As String = "Hello there"
Dim Occurrences As Integer = (input.Length - input.Replace(phrase, String.Empty).Length) / phrase.Length
You just need to make sure that phrase.Length > 0.
the best way to do it is this:
Public Function countString(ByVal inputString As String, ByVal stringToBeSearchedInsideTheInputString as String) As Integer
Return System.Text.RegularExpressions.Regex.Split(inputString, stringToBeSearchedInsideTheInputString).Length -1
End Function
str="Thisissumlivinginsumgjhvgsum in the sum bcoz sum ot ih sum"
b= LCase(str)
array1=Split(b,"sum")
l=Ubound(array1)
msgbox l
the output gives u the no. of occurences of a string within another one.
You can create a Do Until loop that stops once an integer variable equals the length of the string you're checking. If the phrase exists, increment your occurences and add the length of the phrase plus the position in which it is found to the cursor variable. If the phrase can not be found, you are done searching (no more results), so set it to the length of the target string. To not count the same occurance more than once, check only from the cursor to the length of the target string in the Loop (strCheckThisString).
Dim input As String = "hello there. this is a test. hello there hello there!"
Dim phrase As String = "hello there"
Dim Occurrences As Integer = 0
Dim intCursor As Integer = 0
Do Until intCursor >= input.Length
Dim strCheckThisString As String = Mid(LCase(input), intCursor + 1, (Len(input) - intCursor))
Dim intPlaceOfPhrase As Integer = InStr(strCheckThisString, phrase)
If intPlaceOfPhrase > 0 Then
Occurrences += 1
intCursor += (intPlaceOfPhrase + Len(phrase) - 1)
Else
intCursor = input.Length
End If
Loop
You just have to change the input of the split function into a string array and then delare the StringSplitOptions.
Try out this line of code:
Occurrences = input.Split({phrase}, StringSplitOptions.None).Length
I haven't checked this, but I'm thinking you'll also have to account for the fact that occurrences would be too high due to the fact that you're splitting using your string and not actually counting how many times it is in the string, so I think Occurrences = Occurrences - 1
Hope this helps
You could create a recursive function using IndexOf. Passing the string to be searched and the string to locate, each recursion increments a Counter and sets the StartIndex to +1 the last found index, until the search string is no longer found. Function will require optional parameters Starting Position and Counter passed by reference:
Function InStrCount(ByVal SourceString As String, _
ByVal SearchString As String, _
Optional ByRef StartPos As Integer = 0, _
Optional ByRef Count As Integer = 0) As Integer
If SourceString.IndexOf(SearchString, StartPos) > -1 Then
Count += 1
InStrCount(SourceString, _
SearchString, _
SourceString.IndexOf(SearchString, StartPos) + 1, _
Count)
End If
Return Count
End Function
Call function by passing string to search and string to locate and, optionally, start position:
Dim input As String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase As String = "hello there"
Dim Occurrences As Integer
Occurrances = InStrCount(input.ToLower, phrase.ToLower)
Note the use of .ToLower, which is used to ignore case in your comparison. Do not include this directive if you do wish comparison to be case specific.
One more solution based on InStr(i, str, substr) function (searching substr in str starting from i position, more info about InStr()):
Function findOccurancesCount(baseString, subString)
occurancesCount = 0
i = 1
Do
foundPosition = InStr(i, baseString, subString) 'searching from i position
If foundPosition > 0 Then 'substring is found at foundPosition index
occurancesCount = occurancesCount + 1 'count this occurance
i = foundPosition + 1 'searching from i+1 on the next cycle
End If
Loop While foundPosition <> 0
findOccurancesCount = occurancesCount
End Function
As soon as there is no substring found (InStr returns 0, instead of found substring position in base string), searching is over and occurances count is returned.
Looking at your original attempt, I have found that this should do the trick as "Split" creates an array.
Occurrences = input.split(phrase).ubound
This is CaSe sensitive, so in your case the phrase should equal "Hello there", as there is no "hello there" in the input
Expanding on Sumit Kumar's simple solution, here it is as a one-line working function:
Public Function fnStrCnt(ByVal str As String, ByVal substr As String) As Integer
fnStrCnt = UBound(Split(LCase(str), substr))
End Function
Demo:
Sub testit()
Dim thePhrase
thePhrase = "Once upon a midnight dreary while a man was in a house in the usa."
If fnStrCnt(thePhrase, " a ") > 1 Then
MsgBox "Found " & fnStrCnt(thePhrase, " a ") & " occurrences."
End If
End Sub 'testit()
I don't know if this is more obvious?
Starting from the beginning of longString check the next characters up to the number characters in phrase, if phrase is not found start looking from the second character etc. If it is found start agin from the current position plus the number of characters in phrase and increment the value of occurences
Module Module1
Sub Main()
Dim longString As String = "Hello there. My name is John. I work very hard. Hello there! Hello therehello there"
Dim phrase As String = "hello There"
Dim occurences As Integer = 0
Dim n As Integer = 0
Do Until n >= longString.Length - (phrase.Length - 1)
If longString.ToLower.Substring(n, phrase.Length).Contains(phrase.ToLower) Then
occurences += 1
n = n + (phrase.Length - 1)
End If
n += 1
Loop
Console.WriteLine(occurences)
End Sub
End Module
I used this in Vbscript, You can convert the same to VB.net as well
Dim str, strToFind
str = "sdfsdf:sdsdgs::"
strToFind = ":"
MsgBox GetNoOfOccurranceOf( strToFind, str)
Function GetNoOfOccurranceOf(ByVal subStringToFind As String, ByVal strReference As String)
Dim iTotalLength, newString, iTotalOccCount
iTotalLength = Len(strReference)
newString = Replace(strReference, subStringToFind, "")
iTotalOccCount = iTotalLength - Len(newString)
GetNoOfOccurranceOf = iTotalOccCount
End Function
I know this thread is really old, but I got another solution too:
Function countOccurencesOf(needle As String, s As String)
Dim count As Integer = 0
For i As Integer = 0 to s.Length - 1
If s.Substring(i).Startswith(needle) Then
count = count + 1
End If
Next
Return count
End Function