Put a space in front of every capital letter in a string - string

I want to put spaces before each capital letter in a string.
So turn this: TheQuickBrownFox
into this: The Quick Brown Fox
This is the code I have so far: it finds uppercase chars in the string and shows each upper letter in a Message Box.
I can't figure out where to go from here:
Dim input As String = "TheQuickBrownFox"
For i As Integer = 0 To input.Length - 1
Dim c As Char = input(i)
If Char.IsUpper(c) Then
MsgBox(c)
End If
Next
I've googled around but I wasn't able to find a solution for visual basic.

A couple of example using LINQ:
Imports System.Linq
Imports System.Text
Dim input As String = "TheQuickBrownFox"
In case you don't know it, a String is a collection of Chars, so you can iterate the string content using a ForEach loop (e.g., For Each c As Char In input).
▶ Generate a string from an collection of chars (Enumerable(Of Char)), excluding the first uppercase char if it's the first in the string.
The second parameter of a Select() method, when specified (in Select(Function(c, i) ...)), represents the index of the element currently processed.
String.Concat() rebuilds a string from the Enumerable(Of Char) that the Select() method generates:
Dim result = String.Concat(input.Select(Function(c, i) If(i > 0 AndAlso Char.IsUpper(c), ChrW(32) + c, c)))
The same, not considering the position of the first uppercase char:
Dim result = String.Concat(input.Select(Function(c) If(Char.IsUpper(c), ChrW(32) + c, c)))
▶ With an aggregation function that uses a StringBuilder as accumulator (still considering the position of the first uppercase char).
When processing strings, a StringBuilder used as storage can make the code more efficient (creates way less garbage) and more performant.
See, e.g., here: How come for loops in C# are so slow when concatenating strings?
➨ Note that I'm adding an Array of chars to the StringBuilder:
Dim result = input.Aggregate(New StringBuilder(),
Function(sb, c) sb.Append(If(sb.Length > 0 AndAlso Char.IsUpper(c), {ChrW(32), c}, {c})))
➨ result is a StringBuilder object: extract the string with result.ToString().
Or, as before, without considering the position:
Dim result = input.Aggregate(New StringBuilder(),
Function(sb, c) sb.Append(If(Char.IsUpper(c), {ChrW(32), c}, {c})))
▶ The two example above are somewhat equivalent to a simple loop that iterates all chars in the string and either creates a new string or uses a StringBuilder as storage:
Dim sb As New StringBuilder()
For Each c As Char In input
sb.Append(If(sb.Length > 0 AndAlso Char.IsUpper(c), {ChrW(32), c}, {c}))
Next
Change the code as described before if you want to add a space to the first uppercase Char without considering its position.

Yet another option is a language extension method.
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Demo()
Console.ReadLine()
End Sub
Private Sub Demo()
Dim data = New List(Of String) From
{
"ThisIsASentence",
"TheQuickBrownFox",
"ApplesOrangesGrapes"}
data.ForEach(Sub(item) Console.WriteLine($"{item,-25}[{item.SplitCamelCase}]"))
End Sub
End Module
Public Module StringExtensions
<Runtime.CompilerServices.Extension>
Public Function SplitCamelCase(sender As String) As String
Return Regex.Replace(Regex.Replace(sender,
"(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"),
"(\p{Ll})(\P{Ll})",
"$1 $2")
End Function
End Module

You can use a regular expression:
Dim input = "TheQuickBrownFox"
Dim withSpaces = Regex.Replace(a, "(?<!^)([A-Z])", " $1")
The regex finds any uppercase A-Z that are not preceded by the start of the string and captures it into a group. The replacement takes the group content and prefixes a space
If you don't want to use the negative lookbehind, you can trim the result:
Dim withSpaces = Regex.Replace(a, "([A-Z])", " $1").TrimStart()
Or don't trim if you don't care that the string starts with a space

To expand on your code:
Dim input As String = "TheQuickBrownFox"
Dim outputSB as new StringBuilder
For i As Integer = 0 To input.Length - 1
Dim c As Char = input(i)
If Char.IsUpper(c) Then
outputSB.Append(" ")
'MsgBox(c)
End If
outputSB.Append(c)
Next
Console.Writeline(outputSB.ToString())

Related

Split String New Line After 3 Space in VB.net

i have problem to split string into newline in vb.net.
right now i can make it to split by a single space.i want split new line after 3 space.
Dim s As String = "SOMETHING BIGGER THAN YOUR DREAM"
Dim words As String() = s.Split(New Char() {" "c})
For Each word As String In words
Console.WriteLine(word)
Next
output :
SOMETHING
BIGGER
THAN
YOUR
DREAM
Desire output :
SOMETHING BIGGER THAN
YOUR DREAM
Another alternative added to existing efficient answers might to be:
Dim separator As Char = CChar(" ")
Dim sArr As String() = "SOMETHING BIGGER THAN YOUR DREAM".Split(separator)
Dim indexOfSplit As Integer = 3
Dim sFinal As String = Join(sArr.Take(indexOfSplit).ToArray, separator) & vbNewLine &
Join(sArr.Skip(indexOfSplit).ToArray, separator)
Console.WriteLine(sFinal)
You can split your input string, then loop the array of parts generated and add them to a StringBuilder object.
When you have read a number of parts that is multiple of a defined value, (wordsPerLine, here), you append vbNewLine to the current part.
When the loop completes, print the content of the StringBuilder to the Console:
Dim input As String = "SOMETHING BIGGER THAN YOUR DREAM, NOT MORE THAN YOUR ACCOUNT BALANCE"
Dim wordsPerLine As Integer = 3
Dim wordsCounter As Integer = 1
Dim sb As StringBuilder = New StringBuilder()
For Each word As String In input.Split()
sb.Append(word & If(wordsCounter Mod wordsPerLine = 0, vbNewLine, " "))
wordsCounter += 1
Next
Console.WriteLine(sb.ToString())
Prints:
SOMETHING BIGGER THAN
YOUR DREAM, NOT
MORE THAN YOUR
ACCOUNT BALANCE
Instead of using split, you might capture 3 words in a capturing group and match the trailing whitespace chars.
In the replacement use the group followed by a newline.
Pattern
(\S+(?:\s+\S+){2})\s*
That will match:
( Capture group 1
\S+ Match 1+ non whitespace chars
(?:\s+\S+){2} Repeat 2 times matching 1+ whitespace chars and 1+ non whitespace chars
) Close group 1
\s* Match trailing whitespace chars
.NET Regex demo | VB.NET demo
Example code
Dim s As String = "SOMETHING BIGGER THAN YOUR DREAM"
Dim output As String = Regex.Replace(s, "(\S+(?:\s+\S+){2})\s*", "$1" + Environment.NewLine)
Console.WriteLine(output)
Output
SOMETHING BIGGER THAN
YOUR DREAM
String.Join has an overload that will help you.
First parameter is the character to use between elements of your array.
Second parameter is the array you wish to join.
Third parameter is the starting position, for the first line in your desired output this would be the element at index 0.
Fourth parameter is the length to use, for the first line we want three array elements.
Private Sub OPCode()
Dim s As String = "SOMETHING BIGGER THAN YOUR DREAM"
Dim words As String() = s.Split(New Char() {" "c})
Dim line1 As String = String.Join(" ", words, 0, 3)
Console.WriteLine(line1)
Dim line2 As String = String.Join(" ", words, 3, words.Length - 3)
Console.WriteLine(line2)
End Sub

How to delete text from a textbox from starting to first "," comma in a sentence?

I want to delete all the words in a textbox from starting to the first comma appearance.
Example -
Ram bought rice, bread and tomatoes.
The above sentence should become -
bread and tomatoes.
I know how to replace texts in VB.Net but I can't find a solution for this issue.
Try this:
Dim s As String = "Ram bought rice, bread and tomatoes."
Dim index As Integer = s.IndexOf(",") + 1
Dim substring As String = s.Substring(index , s.Length - index)
This is an example how to do it.
Module Example
Sub Main()
Dim str As String = "foo, bar baz"
Dim index As Integer = str.IndexOf(",") + 1
Dim length As Integer = str.Length - index
str = str.Substring(index, length)
Console.WriteLine(str)
Console.ReadLine()
End Sub
End Module
I know I'm a little late to the party, but here is how I would do it using a function.
Private Function Foo(ByVal str As String) As String
If str.Contains(",") Then
Return str.Split(",")(1).Trim()
End If
''return nothing as the user only wants the 2nd half of the string
Return Nothing
End Function
Trim() will remove any leading spaces.
You can call the function like so,
Dim value As String = "Ram bought rice, bread and tomatoes."
textBox1.Text = Foo(value)
Output: bread and tomatoes.
The other answers are nice, but adding the 2nd parameter gives an un-needed risk. Try this for safer code
Dim MyString As String = "Ram bought rice, bread and tomatoes."
Dim index As Integer = MyString.IndexOf(",") + 1
Dim MyNewString As String = MyString.Substring(index)
This just uses the first parameter, as the second calculation to calculate the length is not needed.

Replace a string with a format string

I have the following input:
Dim str_format as string = "XXXXX00000"
Dim str as string = "INV"
Dim int as integer = "56"
How can I replace XXXXX with INV and replace 00000 with 56?
For the example above the result should be INVXX00056.
X can only replace with alphabet and 0 can only replace with integer, if str has more than five alphabet. The extra alphabets will be thrown away because str_format only has five X. The same algorithm is true for the integer.
Example 2
Dim str_format as string = "XXX00000"
Dim str as string = "ABCD"
Dim int as integer = 654321
Expected result: ABC54321
Process:
1. ABCD XXX00000 654321
2. ABC DXX000006 54321
3. AB CDX00065 4321
4. A BCD00654 321
5. ABC06543 21
6. ABC65432 1
7. ABC54321
As Spidey mentioned... show some code. That said the process you describe is a bit long-winded.
The Letter part of the solution can be done by grabbing the first 3 characters of str using Left(str,3) this will bring in the leftmost 3 character (if there are less it will get what is there). Then check that you have 3 characters using str.Length(). If the length is less than 3 then append the appropriate number of 'X'.
The Numeric part can be done in a similar way. Your int is actually a string in your code above. If it was a real integer you can cast it to string. Use Right(int,5). Again check to see you have 5 digits and if not prepend with appropriate number of 0.
Have a go... if you run into problems post your code and someone is bound to help.
UPDATE
As there have been actual answers posted here is my solution
Function FormatMyString(str As String, num as String) As String
Dim result As String
result = Left(str,3).PadRight(3, "X"c).ToUpper() & Right(num,5).PadLeft(5, "0"c)
Return result
End Function
UPDATE 2
based on Wiktors answer... made an amendment to my solution to cope with different formats
Function FormatMyString(str As String, num as String, alpha as Integer, digits as Integer) As String
Dim result As String
result = Left(str, alpha).PadRight(alpha, "X"c).ToUpper() & Right(num, digits).PadLeft(digits, "0"c)
Return result
End Function
To use...
FormatMyString("ABCDE", "56",3 5) will return ABC00056
FormatMyString("ABCDE", "123456",4 3) will return ABCD456
FormatMyString("AB", "123456",4 3) will return ABXX456
Here is a possible solution that just uses basic string methods and PadLeft/PadRight and a specific method to count occurrences of specific chars in the string. It assumes the format string can only contain X and 0 in the known order.
Public Function CountCharacter(ByVal value As String, ByVal ch As Char) As Integer
Return value.Count(Function(c As Char) c = ch)
End Function
Public Sub run1()
Dim str_format As String = "XXXXX00000" '"XXX00000"
Dim str As String = "INV"
Dim int As Integer = 56 ' ABC54321
Dim xCnt As Integer = CountCharacter(str_format, "X")
Dim zCnt As Integer = CountCharacter(str_format, "0")
Dim result As String
If xCnt > str.Length Then
result = str.PadRight(xCnt, "X")
Else
result = str.Substring(0, xCnt)
End If
If zCnt > int.ToString().Length Then
result = result & int.ToString().PadLeft(zCnt, "0")
Else
result = result & int.ToString().Substring(int.ToString().Length-zCnt
End If
Console.WriteLine(result)
End Sub
Output for your both scenarios is as expected.
Take a look at this sample
Dim str_format As String = str_format.Replace("XXX", "ABC")
Msgbox(str_format )
As we assume that the X is 3 only. I dont want to give you more it is a start and everything will be easy.
If that kind of format is fix I mean the number of X will go or down then you can make a conditional statement based on the length of string

VBA Regular Expression Mail

I want to split a string into 3 parts. For example i have a email adress like
testuser#gamil.com
and i want to split it into
testuser
gamil
.com
with left, right and mid (str) i only can extract a string if is a fixed lenght.
Has anybody some ideas to make it?
with left, right and mid (str) i only can extract a string if is a fixed length.
This is not actually true, because you can also use the len function to get the length of the string.
Dim L as Integer
L = Len("testuser#gamil.com")
MsgBox L
You can also use the Instr (and InstrRev, reversed) function to find the index of a particular character or substring.
Dim I as Integer
I = Instr("testuser#gamil.com", "#")
So, for your case, a custom function without regex will return an array of three items:
Function SplitEmail(email$)
'Function returns an array like:
' {"username", "domain", "tld"}
Dim Dot As Integer, At As Integer
Dot = InStrRev(email, ".")
At = InStr(email, "#")
Dim ret(1 To 3) As String
ret(1) = Left(email, At - 1)
ret(2) = Mid(email, At + 1, Dot - At - 1)
ret(3) = Mid(email, Dot + 1)
SplitEmail = ret
End Function
To get the username part, you could do:
Dim some_email$
some_email = "testuser#gamil.com"
MsgBox SplitEmail(some_email)(1)

How can I trim a string in BASIC?

How do trim off characters in a string, by how much you want?
For example, say your string is "Tony", but you wanted to display "ny" by trimming of the first two characters, how can this be done?
Sub Main()
Dim s As String
Dim Result As String
s = "Tony"
Result = LTrim(s)
msgbox(Result)
I have this so far using the LTrim function, so how do you specify by how much you want to cut to just display "ny" in the MessageBox?
You don't want LTrim. You want Right:
Result = Right(s, Len(s) - 2);
This will take all but the two left-most characters of s.
You could use the additional string functions to do the same thing,
for example:
X$ = RIGHT$(V$, 2) ' get the ending 2 chars of string
X$ = LEFT$(V$, 2) ' get the leading 2 chars of string
X$ = MID$(V$, 2, 2) ' get 2 chars from the inside of string
Well... If I was trying to clip off the beginning of a string, I would use two functions: StrReverse, and Remove.
I would first reverse the string, then use the remove function to cut off what is now the end, Then flip the remaining string back to it's original state using the reverse function again.
The code would look something like this:
Dim s As String = "Anthony"
Dim index As Integer = 2
Debug.Print(StrReverse(StrReverse(s).Remove(2)))
The output of this would be "ny" and the length will correspond to the index.

Resources