How to remove letters? - vb.net

i just wanna ask:
i have a label40.text
with a content of {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}
and i also have have a label39.text that will change its output everytime a certain changes happens.
My question is
How can i embed this simulation through a code?
If Label39.text = "a" then the content of label40.text "a" will be remove and the list of alphabets will be remain alphabetically.
I want that also to be happen anytime my label39.text will change its value "RANDOMLY"
Example if label39.text = "a,b,c,d,x,z" then
label40.text = "e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y"
this is my code so far
Dim patterns As String
patterns = Label39.Text
Dim tobefollow As String
tobefollow = Label40.Text
Dim matches As MatchCollection = Regex.Matches(patterns, tobefollow)
If Regex.IsMatch(patterns, tobefollow) Then
'this where i will put my code to make my example
End If

First of all, note that you are populating the patterns and tobefollow variables wrongly (you were doing it right in the other question); it should be:
patterns = Label40.Text
tobefollow = Label39.Text
Also bear in mind that what you want can easily be accomplished without relying on Regex; for example via:
If (Label40.Text.ToLower().Contains(Label39.Text.ToLower())) Then
'this where i will put my code to make my example
End If
Regarding what you want this time, you can rely on .Replace: .Replace("text to be deleted", "") will remove this letter; but you have also to account for the commas. Code to be put inside the condition:
Dim origString As String = Label40.Text
Label40.Text = Label40.Text.ToLower().Replace(Label39.Text.ToLower() & ",", "")
If (origString = Label40.Text) Then
'It means that it does not have any comma, that is, refers to the last letter
Label40.Text = Label40.Text.ToLower().Replace("," & Label39.Text.ToLower(), "")
End If

An alternate answer would to use the String.Split and the String.Join Methods to breakdown your strings into individual characters then remove them from the List and join them back together. Here is a Function that does that:
Private Function RemoveLetters(str1 As String, str2 As String) As String
Dim sep() As String = {","}
Dim list1 As List(Of String) = str1.Split(sep, StringSplitOptions.None).ToList
Dim list2 As List(Of String) = str2.Split(sep, StringSplitOptions.None).ToList
For Each s As String In list2
list1.Remove(s)
Next
Return String.Join(",", list1)
End Function
you would use it like this:
Label40.Text = RemoveLetters(Label40.Text, Label39.Text)

Related

How to split on a string instead of a character?

I have a file name like below:
sub_fa__hotchkis_type1a__180310__PUO4x4__180813
I want to separate it with double underscores "__" and using this code:
Dim MdlNameArr() As String = Path.GetFileNameWithoutExtension(strProjMdlName).Split(New Char() {"__"}, StringSplitOptions.RemoveEmptyEntries)
myTool.Label9.Text = MdlNameArr(1).ToString
I expect the result will be "hotchkis_type1a" but it returns "fa".
It doesnt recognize single underscore "_".
Is there any method to use it properly?
You need to split on a string rather than just a character, so if we look at the available overloads for String.Split, we find the nearest one to that is String.Split(string(), options) which takes an array of strings as the separators and requires the inclusion of StringSplitOptions like this:
Dim s = "sub_fa__hotchkis_type1a__180310__PUO4x4__180813"
Dim separators() As String = {"__"}
Dim parts = s.Split(separators, StringSplitOptions.None)
If parts.Length >= 2 Then
Console.WriteLine(parts(1))
Else
Console.WriteLine("Not enough parts found.")
End If
Outputs:
hotchkis_type1a

How to split a string in VBA by more than one character

In C# one can easily split a split string by more than one character, one supplies an array of split characters. I was wondering what is best way to achieve this in VBA. I use VBA.Split typically but to split on more than one characters requires drilling in to the results and sub-splitting the elements. Then one has to re-dimension arrays etc. Quite painful.
Contraints
VBA responses only please. You may use .NET collection classes if you wish (yes they are creatable and callable in VBA). You may use JSON, XML as vessels for the list of split segments if you wish. You may use the humble VBA.Collection class if you wish, or even a Scripting.Dictionary. You may use even a fabricated recordset if you wish.
I know full well one can write a .NET asssembly to call the .NET String.Split method and expose assembly to VBA with COM interfaces but where is the challenge in that.
This should be fairly easy to do with a regular expression. If you match on the negation of the passed characters to split on, the matches will be the members of the output array. The upside to doing this is that the output array only needs to be sized once because you can get a count of the matches returned by the RegExp. The pattern is fairly simple to build - it boils down to something like [^abc]+ where 'a', 'b', and 'c' are the characters to split on. About the only thing that you need to do to prepare the expression is to escape a couple characters that have special meaning in that context inside a regular expression (I probably forgot some):
Private Function BuildRegexPattern(ByVal inputString As String) As String
Dim escapeTargets() As String
escapeTargets = VBA.Split("- ^ \ ]")
Dim returnValue As String
returnValue = inputString
Dim idx As Long
For idx = LBound(escapeTargets) To UBound(escapeTargets)
returnValue = Replace$(returnValue, escapeTargets(idx), "\" & escapeTargets(idx))
Next
BuildRegexPattern = "[^" & returnValue & "]+"
End Function
Once you have the pattern, it's just a simple matter of sizing the array and iterating over the matches to assign them (plus some other special case handling, etc.):
Public Function MultiSplit(ByVal toSplit As String, Optional ByVal delimiters As String = " ") As String()
Dim returnValue() As String
If toSplit = vbNullString Then
returnValue = VBA.Split(vbNullString)
Else
With New RegExp
.Pattern = BuildRegexPattern(IIf(delimiters = vbNullString, " ", delimiters))
.MultiLine = True
.Global = True
If Not .Test(toSplit) Then
'Only delimiters.
ReDim returnValue(Len(toSplit) - 1)
Else
Dim matches As Object
Set matches = .Execute(toSplit)
ReDim returnValue(matches.Count - 1)
Dim idx As Long
For idx = LBound(returnValue) To UBound(returnValue)
returnValue(idx) = matches(idx)
Next
End If
End With
End If
MultiSplit = returnValue
End Function
In my attempt, I replace all the other characters with space before splitting on space. (So I cheat a little.)
Private Function SplitByMoreThanOneChars(ByVal sLine As String)
'*
'* Brought to you by the Excel Development Platform Blog
'* http://exceldevelopmentplatform.blogspot.com/2018/11/
'*
'* Don't get excited, this splits by spaces only
'* we fake splitting by multiple characters by replacing those characters
'* with spaces
'*
Dim vChars2 As Variant
vChars2 = Array(" ", "<", ">", "[", "]", "(", ")", ";")
Dim sLine2 As String
sLine2 = sLine
Dim lCharLoop As Long
For lCharLoop = LBound(vChars2) To UBound(vChars2)
Debug.Assert Len(vChars2(lCharLoop)) = 1
sLine2 = VBA.Replace(sLine2, vChars2(lCharLoop), " ")
Next
SplitByMoreThanOneChars = VBA.Split(sLine2)
End Function

Lowercase the first word

Does anybody know how to lowercase the first word for each line in a textbox?
Not the first letter, the first word.
I tried like this but it doesn't work:
For Each iz As String In txtCode.Text.Substring(0, txtCode.Text.IndexOf(" "))
iz = LCase(iz)
Next
When you call Substring, it is making a copy of that portion of the string and returning it as a new string object. So, even if you were successfully changing the value of that returned sub-string, it still would not change the original string in the Text property.
However, strings in .NET are immutable reference-types, so when you set iz = ... all you are doing is re-assigning the iz variable to point to yet another new string object. When you set iz, you aren't even touching the value of that copied sub-string to which it previously pointed.
In order to change the value of the text box, you must actually assign a new string value to its Text property, like this:
txtCode.Text = "the new value"
Since that is the case, I would recommend building a new string, using a StringBuilder object, and then, once the modified string is complete, then set the text box's Text property to that new string, for instance:
Dim builder As New StringBuilder()
For Each line As String In txtCode.Text.Split({Environment.NewLine}, StringSplitOptions.None)
' Fix case and append line to builder
Next
txtCode.Text = builder.ToString()
The solutions here are interesting but they are ignoring a fundamental tool of .NET: regular expressions. The solution can be written in one expression:
Dim result = Regex.Replace(txtCode.Text, "^\w+",
Function (match) match.Value.ToLower(), RegexOptions.Multiline)
(This requires the import System.Text.RegularExpressions.)
This solution is likely more efficient than all the other solutions here (It’s definitely more efficient than most), and it’s less code, thus less chance of a bug and easier to understand and to maintain.
The problem with your code is that you are running the loop only on each character of the first word in the whole TextBox text.
This code is looping over each line and takes the first word:
For Each line As String In txtCode.Text.Split(Environment.NewLine)
line = line.Trim().ToLower()
If line.IndexOf(" ") > 0 Then
line = line.Substring(0, line.IndexOf(" ")).Trim()
End If
// do something with 'line' here
Next
Loop through each of the lines of the textbox, splitting all of the words in the line, making sure to .ToLower() the first word:
Dim strResults As String = String.Empty
For Each strLine As String In IO.File.ReadAllText("C:\Test\StackFlow.txt").Split(ControlChars.NewLine)
Dim lstWords As List(Of String) = strLine.Split(" ").ToList()
If Not lstWords Is Nothing Then
strResults += lstWords(0).ToLower()
If lstWords.Count > 1 Then
For intCursor As Integer = 1 To (lstWords.Count - 1)
strResults += " " & lstWords(intCursor)
Next
End If
End If
Next
I used your ideas guys and i made it up to it like this:
For Each line As String In txtCode.Text.Split(Environment.NewLine)
Dim abc() As String = line.Split(" ")
txtCode.Text = txtCode.Text.Replace(abc(0), LCase(abc(0)))
Next
It works like this. Thank you all.

Find and replace using Listbox Vb.net

ok have a list of 84000 words , and have some articles in these articles i want to replace first occurrence of each word i have in listbox e.g
For Each item In ListBox1.Items
Dim mytext As String = "My some text this text is very long text and i want to replace this"
If ListBox1.Items.Contains(mytext) Then
mytext = Replace(mytext, mytext, "String to replace",Count:=1)
End If
Next
but it used to replace the whole mytext i want to replace words in mytext and also it hang the system and very very slow and help or idea please
It looks like you want to replace everything with the same string, but the code below is easily adaptable to other cases but I go with it for now.
To simplify I am assuming that you want to replace words and the words are only seperated by spaces (' ').
First make a dictionary out of the Items in the listbox:
dim dict = ListBox1.Items.Cast(of object).ToDictionary(function(x) x.ToString())
Then get yourself all words:
dim words = mytext.Split(New [Char](){" "c});
and a word-transform:
dim replaceWith = "your replacement";
dim mapWords as Func(of string,string) = _
function(word) IIf(dict.ContainsKey(word), replaceWith, word)
then transform the words and concatenate them again with ' ':
dim result = String.Join(" ", words.Select(function(word) mapWords(word)))
and you should be done.
If you want to replace with separate words just make the dictionaries values your replacement and switch the mapWords-function with
dim mapWords as Func(of string,string) = _
function(word) IIf(dict.ContainsKey(word), dict(word), word)

String Array Thing!

Right - to start with, I'm entering unfamiliar areas with this - so please be kind!
I have a script that looks a little something like this:
Private Function checkString(ByVal strIn As String) As String
Dim astrWords As String() = New String() {"bak", "log", "dfd"}
Dim strOut As String = ""
Dim strWord As String
For Each strWord In astrWords
If strIn.ToLower.IndexOf(strWord.ToLower, 0) >= 0 Then
strOut = strWord.ToLower
Exit For
End If
Next
Return strOut
End Function
It's function is to check the input string and see if any of those 'astrWords' are in there and then return the value.
So I wrote a bit of code to dynamically create those words that goes something like this:
Dim extensionArray As String = ""
Dim count As Integer = 0
For Each item In lstExtentions.Items
If count = 0 Then
extensionArray = extensionArray & """." & item & """"
Else
extensionArray = extensionArray & ", ""." & item & """"
End If
count = count + 1
Next
My.Settings.extensionArray = extensionArray
My.Settings.Save()
Obviously - it's creating that same array using list items. The output of that code is exactly the same as if I hard coded it - but when I change the first bit of code to:
Dim astrWords As String() = New String() {My.Settings.extensionArray}
instead of:
Dim astrWords As String() = New String() {"bak", "log", "dfd"}
It starts looking for the whole statement instead of looping through each individual one?
I think it has something to do with having brackets on the end of the word string - but I'm lost!
Any help appreciated :)
When you use the string from the settings in the literal array, it's just as if you used a single strings containing the delimited strings:
Dim astrWords As String() = New String() {"""bak"", ""log"", ""dfd"""}
What you probably want to do is to put a comma separated string like "bak,log,dfd" in the settings, then you can split it to get it as an array:
Dim astrWords As String() = My.Settings.extensionArray.Split(","C)
You need to set extensionArray up as a string array instead of simply a string.
Note that
Dim something as String
... defines a single string, but
Dim somethingElse as String()
... defines a whole array of strings.
I think with your code, you need something like:
Dim extensionArray As String() = new String(lstExtensions.Items)
Dim count As Integer = 0
For Each item In lstExtentions.Items
extensionArray(count) = item
count = count + 1
Next
My.Settings.extensionArray = extensionArray
My.Settings.Save()
Then at the start of checkString you need something like
Private Function checkString(ByVal strIn As String) As String
Dim astrWords As String() = My.Settings.extensionArray
...
There also might be an even easier way to turn lstExtentions.Items into an Array if Items has a 'ToArray()' method, but I'm not sure what Type you are using there...
What you've done is created a single string containing all 3 words. You need to create an array of strings.
New String() {"bak", "log", "dfd"}
means create a new array of strings containing the 3 strings values "bak", "log" and "dfd".
New String() {My.Settings.extensionArray}
means create a new array of strings containing just one value which is the contents of extensionArray. (Which you have set to ""bak", "log", "dfd""). Note this is one string, not an array of strings. You can't just create 1 string with commas in it, you need to create an array of strings.
If you want to create your array dynamically, you need to define it like this:
Dim astrWords As String() = New String(3)
This creates an array with 3 empty spaces.
You can then assign a string to each space by doing this:
astrWords(0) = "bak"
astrWords(1) = "log"
astrWords(2) = "dfd"
You could do that bit in a for loop:
Dim count As Integer = 0
For Each item In lstExtentions.Items
astrWords(count) = item
count = count + 1
Next
Alternatively, you could look at using a generic collection. That way you could use the Add() method to add multiple strings to it
I think you want your extensionArray to be of type String() and not String. When you are trying to initialize the new array, the initializer doesn't know to parse out multiple values. It just sees your single string.