Check if two strings are anagrams in VB [closed] - regex

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm making a little anagram solving game in VB and I'd like to verify that the given word fits the letters given. For example, the string eliter shouldn't match letter because t only appears once in the above string. I already have a check to determine if the submission is a word, but ideally, a check to make sure it fits the letters given would be wrapped around that statement.
Public Class Form1
Public Function GenerateRandomString(ByRef iLength As Integer) As String
Dim rdm As New Random()
Dim allowChrs() As Char = "ABCDEFGHIJKLOMNOPQRSTUVWXYZ".ToCharArray()
Dim sResult As String = ""
For i As Integer = 0 To iLength - 1
sResult += allowChrs(rdm.Next(0, allowChrs.Length))
Next
Return sResult
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
countdown.Enabled = True
lbl_countdown.Text = "10"
lbl_anagram.Text = GenerateRandomString(9)
End Sub
Private Sub countdown_Tick(sender As Object, e As EventArgs) Handles countdown.Tick
lbl_countdown.Text -= 1
If lbl_countdown.Text < 1 Then
countdown.Enabled = False
MsgBox("End of game")
Dim wordList As HashSet(Of String) = New HashSet(Of String)(File.ReadAllLines("words_alpha.txt"))
If Not wordList.Contains(TextBox1.Text.ToString()) Then
MsgBox("Not found")
Else
MsgBox("Found")
End If
End If
End Sub
End Class
Note that this needs to be in VB and preferably requires no extra libraries, etc.
Also note that you don't have to use all the letter but can't use more than what's available!
Thanks in advance!

You just need to sort your string alphabetically and compare the sorted string. Two anagram will have the same string when the characters are sorted.
Sub Main()
Dim s As String = "betjwepfw"
Console.WriteLine(s)
Console.WriteLine(New String(s.OrderBy(Function(c) c).ToArray()))
Console.ReadLine()
End Sub

Related

Text editing in visual basic

At the push of a button, I need a way to remove everything but numbers from a textbox and group numbers 6 in a row with a comma , to separate them.
Example:
Text in textbox:
416782 167490ai|189037jkn
expected result:
416782,167490,189037
Any help is much appreciated :)
I've got as far as this, and it gives me the right output and removes everything but numbers. I just need to add a comma every 6 characters.
Private Sub copypdmbutton_Click(sender As Object, e As EventArgs) _
Handles copypdmbutton.Click
Dim input As String = textbox.Text
Dim output As String = textbox2.Text
output = (System.Text.RegularExpressions.Regex.Replace(input, "[^\d]", ""))
'removes everything except numbers
textbox2.Text = output
End Sub
Fortunately for us, a String is a sequential collection of Char. We can use this fact by looping through each Char in the String from the text box. We only add the numbers (digits) to the new string.
I then build the result string using Substring(start Index, length) followed by a comma.
This code only works if the length of numberString is evenly divisible by 6. The Mod operator tells us this. I will leave it to you to decide how to handle the edge case. Hint: The last sb.Append can use Substring(start Index) The missing second parameters means that the substring will continue to the end of the original string.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1.Text = "416782 167490ai|189037jkn"
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim s = TextBox1.Text
Dim sb As New StringBuilder
For Each c As Char In s
If Char.IsDigit(c) Then
sb.Append(c)
End If
Next
Dim numberString = sb.ToString
sb.Clear()
If numberString.Length Mod 6 = 0 Then
For i = 0 To numberString.Length - 6 Step 6
sb.Append(numberString.Substring(i, 6) & ",")
Next
End If
TextBox1.Text = sb.ToString.Trim(","c)
End Sub
If you NuGet "System.Interactive" to get the Buffer operator, then this code does the job:
Dim input As String = "3434jh34kjh3b4k34m34kj43434"
Dim output As String =
String.Join(
",", _
input _
.Where(Function (x) Char.IsDigit(x)) _
.Buffer(6) _
.Select(Function (xs) String.Concat(xs)))
Console.WriteLine(output)
For my sample input I get this out:
343434,343434,43434

Regex find all first unique occurences of character in a string [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have following string
1,2,3,a,b,c,a,b,c,1,2,3,c,b,a,2,3,1,
I would like to get only the first occurrence of any number without changing the order. This would be
1,2,3,a,b,c,
With this regex (found # https://stackoverflow.com/a/29480898/9307482) I can find them, but only the last occurrences. And this reverses the order.
(\w)(?!.*?\1) (https://regex101.com/r/3fqpu9/1)
It doesn't matter if the regex ignores the comma. The order is important.
Regular expression is not meant for that purpose. You will need to use an index filter or Set on array of characters.
Since you don't have a language specified I assume you are using javascript.
Example modified from: https://stackoverflow.com/a/14438954/1456201
String.prototype.uniqueChars = function() {
return [...new Set(this)];
}
var unique = "1,2,3,a,b,c,a,b,c,1,2,3,c,b,a,2,3,1,".split(",").join('').uniqueChars();
console.log(unique); // Array(6) [ "1", "2", "3", "a", "b", "c" ]
I would use something like this:
// each index represents one digit: 0-9
const digits = new Array(10);
// make your string an array
const arr = '123abcabc123cba231'.split('');
// test for digit
var reg = new RegExp('^[0-9]$');
arr.forEach((val, index) => {
if (reg.test(val) && !reg.test(digits[val])) {
digits[val] = index;
}
});
console.log(`occurrences: ${digits}`); // [,0,1,2,,,,....]
To interpret, for the digits array, since you have nothing in the 0 index you know you have zero occurrences of zero. Since you have a zero in the 1 index, you know that your first one appears in the first character of your string (index zero for array). Two appears in index 1 and so on..
A perl way to do the job:
use Modern::Perl;
my $in = '4,d,e,1,2,3,4,a,b,c,d,e,f,a,b,c,1,2,3,c,b,a,2,3,1,';
my (%h, #r);
for (split',',$in) {
push #r, $_ unless exists $h{$_};
$h{$_} = 1;
}
say join',',#r;
Output:
4,d,e,1,2,3,a,b,c,f

Replace a specific portion of string after a specific starting substring using regex [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a string like this
"This is an example. Start color=BLUE and rest of the string"
I want to find "color=" coming after "Start" and replace "color=BLUE" with "color=None".
"color=BLUE" always comes after "Start". But "Start" can be anywhere in the entire string.
How I can do this using regex?
I would use pure, efficient string methods, this works even if there are multiple color after Start:
Dim s = "This is an example. Start color=BLUE and rest of color=Green the string"
Dim startIndex = s.IndexOf("Start", StringComparison.Ordinal)
If startIndex = -1 Then Return s ' or do whatever you want, there is no starting point
Dim colorIndex = s.IndexOf("color=", startIndex, StringComparison.Ordinal)
While colorIndex >= 0
colorIndex += "color=".Length
Dim endIndex = s.IndexOf(" ", colorIndex, StringComparison.Ordinal)
If endIndex = -1 Then Exit While
Dim oldColor = s.Substring(colorIndex, endIndex - colorIndex) ' just out of interest
Dim newColor = "None"
s = $"{s.Remove(colorIndex)}{newColor}{s.Substring(endIndex)}"
colorIndex = s.IndexOf("color=", endIndex, StringComparison.Ordinal)
End While
If you want to find also start or COLOR, so ignore the case, use for example s.IndexOf("color=", startIndex, StringComparison.OrdinalIgnoreCase).
An easy solution without regex :
MyString.Replace("color=Blue","color=None")
The Replace method replaces any portion of given string with the target string.
Hope this helps :)

dict to remove smart quotes [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
charmap = [
(u"\u201c\u201d", "\""),
(u"\u2018\u2019", "'")
]
_map = dict((c, r) for chars, r in charmap for c in list(chars))
fixed = "".join(_map.get(c, c) for c in s)
print fixed
I was looking to write a similar script to replace smart quotes and curly apostrophes from text answered here here: Would someone be kind enough to explain the two lines:
_map = dict((c, r) for chars, r in charmap for c in list(chars))
fixed = "".join(_map.get(c, c) for c in s)
and possibly rewrite them in a longer-winded format with comments to explain what is exactly going on - I'm a little confused whether its an inner/outer loop combo or sequential checking over items in a dictionary.
_map = dict((c, r) for chars, r in charmap for c in list(chars))
means:
_map = {} # an empty dictionary
for (c, r) in charmap: # c - string of symbols to be replaced, r - replacement
for chars in list(c): # chars - individual symbol from c
_map[chars] = r # adding entry replaced:replacement to the dictionary
and
fixed = "".join(_map.get(c, c) for c in s)
means
fixed = "" # an empty string
for c in s:
fixed = fixed + _map.get(c, c) # first "c" is key, second is default for "not found"
as method .joinsimply concatenates elements of sequence with given string as a separators between them (in this case "", i. e. without a separator)
It's faster and more straightforward to use the built in string function translate:
#!python2
#coding: utf8
# Start with a Unicode string.
# Your codecs.open() will read the text in Unicode
text = u'''\
"Don't be dumb"
“You’re smart!”
'''
# Build a translation dictionary.
# Keys are Unicode ordinal numbers.
# Values can be ordinals, Unicode strings, or None (to delete)
charmap = { 0x201c : u'"',
0x201d : u'"',
0x2018 : u"'",
0x2019 : u"'" }
print text.translate(charmap)
Output:
"Don't be dumb"
"You're smart!"

Getting numbers out of cells with text and producing a list with all these numbers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a column given to me in a spreadsheet which looks like that:
What I need is to get all the references out, the ones in square brackets, to provide with the full list to a user:
... and then get a full list of all references, as follows:
Does anyone have an idea of how I can do this using any Excel formulas/filtering or maybe VBA?
assuming:
worksheet to process named after "pressure"
column "A" with cells to get references out of
column "B" to write corresponding extracted references in
column "C"to write full list of all references in
you could try this
Option Explicit
Sub main()
Dim cell As Range
Dim references As String
Dim referencesArr As Variant
With Worksheets("pressure") '<-- change "pressure" to your actual worksheet name
For Each cell In .Range("A1", .Cells(.Rows.Count, 1).End(xlUp))
references = references & GetReferences(cell) & "; "
Next cell
If references <> "" Then
referencesArr = Split(Left(references, Len(references) - 2), ";")
.Range("C1").Resize(UBound(referencesArr)).Value = Application.Transpose(referencesArr)
End If
End With
End Sub
Function GetReferences(rng As Range) As String
Dim arr As Variant, iElem As Long
Dim strng As String
With rng
arr = Split(Replace(Replace(.Value, "[", "|["), "]", "]|"), "|")
For iElem = 1 To UBound(arr) - 1 Step 2
strng = strng & Mid(CStr(arr(iElem)), 2, Len(CStr(arr(iElem))) - 2) & "; "
Next iElem
End With
If strng <> "" Then
GetReferences = Left(strng, Len(strng) - 2)
rng.Offset(, 1) = GetReferences
End If
End Function
There are many examples of regex number parsing¹ from text on this site. Pulling numbers from narrative text is one of the easier regular expression 'patterns'² to construct; especially so with a fixed number of digits regardless of delimiter or grouping character(s).
Put the following into a standard module code sheet.
Option Explicit
Option Base 0 '<~~this is the default but I've included it because it has to be 0
Function numberParse(str As String, _
Optional ndx As Integer = 0, _
Optional delim As String = "; ") As Variant
Dim n As Long, nums() As Variant
Static rgx As Object, cmat As Object
'with rgx as static, it only has to be created once; beneficial when filling a long column with this UDF
If rgx Is Nothing Then
Set rgx = CreateObject("VBScript.RegExp")
Else
Set cmat = Nothing
End If
numberParse = vbNullString
With rgx
.Global = True
.MultiLine = True
.Pattern = "[0-9]{4}"
If .Test(str) Then
Set cmat = .Execute(str)
If CBool(ndx) Then
'pull the index of the array of matches
numberParse = cmat.Item(ndx - 1)
Else
'resize the nums array to accept the matches
ReDim nums(cmat.Count - 1)
'populate the nums array with the matches
For n = LBound(nums) To UBound(nums)
nums(n) = cmat.Item(n)
Next n
'convert the nums array to a delimited string
numberParse = Join(nums, delim)
End If
End If
End With
End Function
With your blurb in A2, put the following into B2,
=numberParse(A2)
With your blurb in A2, put the following into A4 and fill down,
=numberParse(A$2, ROW(1:1))
Your results should resemble the following,
¹ The above was modified from my response in Excel UDF for capturing numbers within characters which wasn't that hard to find.
² See How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops for more information.
For a quick start, you can use =MID(A1,SEARCH("[",A1)+1,SEARCH("]",A1)-SEARCH("[",A1)-1) to extract the text between the brackets. Then you're left with a string, separated by semicolons.
Then, you can run this sub (with tweaking most likely, to narrow down the ranges):
Sub splitSemiColons()
Dim myArray() As String
Dim colToUse As Long
colToUse = 3
myArray = Split(Range("B1"), ";")
Dim i As Long
For i = LBound(myArray) To UBound(myArray)
Cells(i + 1, colToUse).Value = myArray(i)
Next i
End Sub
Or, you can avoid this macro, and just use Data --> Text to Columns --> Use ; delimiter, then copy and paste transposed.