I've been checking all over the internet but really can't find any specific solution of my problem.
How do I check if a string consists of only the declared valid characters?
I want my string to consists of only 0-9, A-Z and a-z
So the string oifrmf9RWGEWRG3oi4m3ofm3mklwef-qæw should be invalid because of - and æ
while the string joidsamfoiWRGWRGmoi34m3f should be valid.
I have been using the build-in RegExp to strip the strings, but is it possible to just make it check and return a boolean false or true?
my regexp:
set pw = new regexp
pw.global = true
pw.pattern = "[^a-zA-Z0-9]"
newstring = pw.replace("iownfiwefnoi3w4mtl3.-34ø'3", "")
Thanks :)
You could do a Test which returns True or False
If( pw.Test("string") ) Then
'' Do something
End If
Try -
Dim myRegExp, FoundMatch
Set myRegExp = New RegExp
myRegExp.Pattern = "[^a-zA-Z0-9]"
FoundMatch = myRegExp.Test("iownfiwefnoi3w4mtl3.-34ø'3")
If FoundMatch is true the RegEx engine has found a character that is not a-z or A-Z or 0-9 and your string is not valid.
You could do something like:
Set match = pw.execute("iownfiwefnoi3w4mtl3.-34ø'3")
if match.count > 0 then
' your pattern matched, so it's invalid
badString = true
else
badString = false
end if
Rather than replace you can look and see if there is a match on any characters outside the whitelist. The general for each match syntax is here
[a-zA-Z0-9] works...I tried it against your string here http://gskinner.com/RegExr/?2u7c3 and here http://regexpal.com/ ...take the carrot out. I also can't remember the regex engine vbscript uses but that might have something to do with your problem. This also works...
\D?\w
Related
Hi I'd like to create a regex that check if my string starts with a / but no matter where shouldn't contains /! so:
/xxxx = true
/xxxx/yyyy = true
/!xxxx = false
/xxxx/!yyyy = false
xxxx = false
I tried this but it doesn't seems to work:
^\/(?!(\/!)(.*|\/!.*))*$
As /!xxxx should also be false, the lookahead should be at the start of the string or else you will miss checking the leading /.
To find /! anywhere in the string, you could prepend .*
^(?!.*/!)/.*
Regex demo
I'm trying to make a pattern that will return false if there's ANYTHING in the string other than exactly what the pattern checks for.
I believe that this is supposed to be achieved by putting the entire pattern between a "^" and a "$".
Sub Macro1()
Dim cellValue As String
cellValue = "7:11 AM NBR Unavail"
Dim callPattern As String
callPattern = "^[1]{0,1}[1-9][:][0-9]{2}[ ]AM|PM$"
Dim regEx As New RegExp
With regEx
.IgnoreCase = False
.Pattern = callPattern
End With
If regEx.Test(cellValue) Then
MsgBox ("Got it!")
Else
MsgBox ("Don't got it...")
End If
End Sub
The variable cellValue has text after the AM|PM that the pattern checks for, yet when I run it I still get the "Got it!" message.
I experimented with the following string and pattern earlier and the "$" at the end worked as intended. Why isn't it working with the above code?
cellValue = "7:11 PM (555) 444-3333"
callPattern = "^[1]{0,1}[1-9][:][0-9]{2}[ ]AM|PM[ ][(][0-9]{3}[)][ ][0-9]{3}[-][0-9]{4}$"
I think you have to enclose parenthesis between AM|PM as following.
callPattern = "^[1]{0,1}[1-9][:][0-9]{2}[ ](AM|PM)$"
Your pattern means
"^[1]{0,1}[1-9][:][0-9]{2}[ ]AM" or "PM$"
also second pattern means
"^[1]{0,1}[1-9][:][0-9]{2}[ ]AM" or "PM[ ][(][0-9]{3}[)][ ][0-9]{3}[-][0-9]{4}$"
You can reduce the pattern down to this:
^1?[1-9]:\d{2} (AM|PM) \(\d{3}\) \d{3}-\d{4}$
Test it here
I am trying to count the number of lower case characters in a string using regex. I think I am missing something blindingly obvious but can't figure out what! It is for an old classic ASP page.
<%
Password="abcd123"
Set myRegExp = New RegExp
myRegExp.Pattern = "(.*[a-z].*)"
Response.Write myRegExp.Execute(Password).Count
%>
The script returns 1 rather than 4.
Your capturing group is wrong, this is enough: ([a-z]). Using the .* you capture all that is around your lowercase character.
I think the following is what you want to do.
Password="abcd123"
Set myRegExp = New RegExp
myRegExp.Global = True ' This is required to get all matches
myRegExp.Pattern = "[a-z]"
Response.Write myRegExp.Execute(Password).Count
But I have some suggestions for you.
You can make your rule greedy with +. This will reduce the cycles.
You need to set .Global to True to get all matches, not only the first one.
With this approach you need to loop through the matches collection (returned from myRegExp.Execute) to find the right result.
Password="abcd123fooBar"
Set myRegExp = New RegExp
myRegExp.Pattern = "[a-z]+"
myRegExp.Global = True
count = 0
For Each match In myRegExp.Execute(Password)
count = count + match.Length
Next
Response.Write count 'prints 9
And here's another way to the same.
This matches with all non-lowercase characters and removes them from the result string. You can then get the length by using Len function.
Password="abcd123fooBar"
Set myRegExp = New RegExp
myRegExp.Pattern = "[^a-z]+"
myRegExp.Global = True
count = Len(myRegExp.Replace(Password, ""))
Response.Write count 'prints 9
Why you don't just use [a-z] instead, because when you use (.*[a-z].*), it will match all your input like one piece and not character by character?
You can check the difference here:
[a-z] regex
(.*[a-z].*) Your regex
I also suggest reading:
The Dot Matches (Almost) Any Character
I want to check if a string contains only uppercase letters and numbers. I have attempted to solve this using RegExp and what I have so far is:
Function CheckForInvalidChars()
dim b
Set re = New RegExp
re.Pattern = "[A-Z_0-9]"
b = re.Test("eS")
msgbox b
End Function
However the variable "b" returns true since I guess it finds a match in the "S" although I want that particular string to return false since not all letters are uppercase. How would I go about achieving this?
I have tried to do this with functions as well using IsNumeric but can't find a IsUpperCase.
Generally speaking, if you want to match whole string using regex, you will usually end up using ^ and $ to describe the start and end of string.
Also, just [A-Z_0-9] matches a single character.
Assuming you don't allow whitespaces, ^[A-Z_0-9]*$ would be the regex you're looking for.
If UCase(s) <> s then there is at least one lower case letter in the string s.
I'd recommend to just UCase the string if you want to enforce uppercase letters. Then you can simplify the check to this:
Function CheckForInvalidChars(s)
Set re = New RegExp
re.Pattern = "^\w+$"
CheckForInvalidChars = re.Test(s)
End Function
teststring = InputBox("Input something")
teststring = UCase(teststring)
WScript.Echo "" & CheckForInvalidChars(teststring)
The escape sequence \w matches word characters, i.e. uppercase letters, lowercase letters (ruled out due to the prior UCase), digits, and underscores. The + rules out empty strings by requiring at least one word character.
#Andris is right, correct the regular expression as follows:
Function CheckForInvalidChars()
dim b
Set re = New RegExp
re.Pattern = "^[A-Z_0-9]*$"
b = re.Test("eS")
msgbox b
End Function
I need to test for a string variable to ensure it matches a specific format:
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
...where x can be any alphanumerical character (a - z, 0 - 9).
I've tried the following, but it doesn't seem to work (test values constantly fail)
If val Like "^([A-Za-z0-9_]{8})([-]{1})([A-Za-z0-9_]{4})([-]{1})([A-Za-z0-9_]{4})([-]{1})([A-Za-z0-9_]{4})([-]{1})([A-Za-z0-9_]{12})" Then
MsgBox "OK"
Else
MsgBox "FAIL"
End If
.
fnCheckSubscriptionID "fdda752d-32de-474e-959e-4b5bf7574436"
Any pointers? I don't mind if this can be achieved in vba or with a formula.
You are already using the ^ beginning-of-string anchor, which is terrific. You also need the $ end-of-string anchor, otherwise in the last group of digits, the regex engine is able to match the first 12 digits of a longer group of digits (e.g. 15 digits).
I rewrote your regex in a more compact way:
^[A-Z0-9]{8}-(?:[A-Z0-9]{4}-){3}[A-Z0-9]{12}$
Note these few tweaks:
[-]{1} can just be expressed with -
I removed the underscores as you say you only want letters and digits. If you do want underscores, instead of [A-Z0-9]{8} (for instance), you can just write \w{8} as \w matches letters, digits and underscores.
Removed the lowercase letters. If you do want to allow lowercase letters, we'll turn on case-insensitive mode in the code (see line 3 of the sample code below).
No need for (capturing groups), so removed the parentheses
We have three groups of four letters and a dash, so wrote (?:[A-Z0-9]{4}-) with a {3}
Sample code
Dim myRegExp, FoundMatch
Set myRegExp = New RegExp
myRegExp.IgnoreCase = True
myRegExp.Pattern = "^[A-Z0-9]{8}-(?:[A-Z0-9]{4}-){3}[A-Z0-9]{12}$"
FoundMatch = myRegExp.Test(SubjectString)
You can do this either with a regular expression, or with just native VBA. I am assuming from your code that the underscore character is also valid in the string.
To do this with native VBA, you need to build up the LIKE string since quantifiers are not included. Also using Option Compare Text makes the "like" action case insensitive.
Option Explicit
Option Compare Text
Function TestFormat(S As String) As Boolean
'Sections
Dim S1 As String, S2_4 As String, S5 As String
Dim sLike As String
With WorksheetFunction
S1 = .Rept("[A-Z0-9_]", 8)
S2_4 = .Rept("[A-Z0-9_]", 4)
S5 = .Rept("[A-Z0-9_]", 12)
sLike = S1 & .Rept("-" & S2_4, 3) & "-" & S5
End With
TestFormat = S Like sLike
End Function
With regular expressions, the pattern is simpler to build, but the execution time may be longer, and that may make a difference if you are processing very large amounts of data.
Function TestFormatRegex(S As String) As Boolean
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.MultiLine = True
.Pattern = "^\w{8}(?:-\w{4}){3}-\w{12}$"
TestFormatRegex = .test(S)
End With
End Function
Sub Test()
MsgBox fnCheckSubscriptionID("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
End Sub
Function fnCheckSubscriptionID(strCont)
' Tools - References - add "Microsoft VBScript Regular Expressions 5.5"
With New RegExp
.Pattern = "^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$"
.Global = True
.MultiLine = True
fnCheckSubscriptionID = .Test(strCont)
End With
End Function
In case of any problems with early binding you can use late binding With CreateObject("VBScript.RegExp") instead of With New RegExp.