vba regular expression last occurrence - regex

I would like to match the "775" (representing the last 3 digit number with an unkown total number of occurrences) within the string "one 234 two 449 three 775 f4our" , with "f4our" representing an unknown number of characters (letters, digits, spaces, but not 3 or more digits in a row).
I came up with the regular expression "(\d{3}).*?$" thinking the "?" would suffice to get the 775 instead of the 234, but this doesn't seem to work.
Is there any way to accomplish this using VBA regular expressions?

Note that (\d{3}).*?$ just matches and captures into Group 1 the first 3 consecutive digits and then matches any 0+ characters other than a newline up to the end of the string.
You need to get the 3 digit chunk at the end of the string that is not followed with a 3-digit chunk anywhere after it.
You may use a negative lookahead (?!.*\d{3}) to impose a restriction on the match:
\d{3}(?!.*\d{3})
See the regex demo. Or - if the 3 digits are to be matched as whole word:
\b\d{3}\b(?!.*\b\d{3}\b)
See another demo

Related

Regular expression to validate the given input which accepts one space or Hyphen which is part of the text length it has minimum and maximum length

The following regex working as expected other than the case that it's not allowed that all characters are the same characters.
^(?=[A-Z0-9]+[ -]?[A-Z0-9]+)(?!([A-Z0-9])(?:\1|[ -]){5,10}).{5,10}$
here minimum is 5 characters and the maximum is 10 characters
11114 allowed its minimum length matched as 5 and one charcter is diff so not all same charcters
11111115 allowed as one charcter is different and its more than 5 charcter.
2222222 not allowed as all are same characters
222-22 not allowed as all are same charcters
111-3 allowed as length 5 and one character is different
444-45 allowed as length more than 5
1234565436 allowed as length with in range 5 to 10
There is no need to repeat range quantifier {5,10} multiple times as that makes changing this regex harder for other cases.
You may use this regex for this:
^(?=.{5,10}$)([A-Z0-9])(?!(?:[ -]?\1)+$)[A-Z0-9]*[ -]?[A-Z0-9]+$
RegEx Demo
RegEx Breakup:
^: Start
(?=.{5,10}$): Assert that we have 5 to 10 chars till end
([A-Z0-9]): Match a letter or digit and capture in group #1
(?!(?:[ -]?\1)+$): Negative lookahead to fail the match if same captured value is repeated till end
[A-Z0-9]*: Match 0 or more letter or digit
[ -]?: Match optional space or hyphen
[A-Z0-9]+: Match 1 or more letter or digit
$: End

Regex to block more than 3 numbers in a string

I am trying to block any strings that contain more than 3 numbers and prevent special characters. I have the special characters part down. I'm just missing the number part.
For example:
"Hello 1234" - Not Allowed
"Hello 123" - Allowed
I've tried the following:
/^[!?., A-Za-z0-9]+$/
/((^[!?., A-Za-z]\d)([0-9]{3}+$))/
/^((\d){2}[a-zA-Z0-9,.!? ])*$/
The last one is the closest I got as it prevents any special characters and any numbers from being entered at all.
I've looked through previous posts, but am coming up short.
Edit for clarification
Essentially I'm trying to find a way to prevent customers from entering PII on a form. No submission should be allowed that contains more than 3 numbers in a string.
Hello1234 - Not allowed
12345 - Not allowed
1111 - not allowed
No where in the comment section when the user enters the string should there be more than 3 numbers in total.
About the patterns that you tried
^[!?., A-Za-z0-9]+$ The pattern matches 1+ times any of the listed, including 1 or more digits
((^[!?., A-Za-z]\d)([0-9]{3}+$)) If {3}+ is supported, the pattern matches a single char from the character class, 1 digit followed by 3 digits
^((\d){2}[a-zA-Z0-9,.!? ])*$ The pattern repeats 0+ times matching 2 digits and 1 of the listed in the character class
You can use a negative lookahead if that is supported to assert not 4 digits in a row.
^(?!.*\d{4})[a-zA-Z0-9,.!? ]+$
regex demo
If there can not be 4 digits in total, but 0-3 occurrences:
^[a-zA-Z,.!? ]*(?:\d[a-zA-Z,.!? ]*){0,3}$
Explanation
^ Start of string
[a-zA-Z,.!? ]* Match 0+ times any of the listed (without a digit)
(?:\d[a-zA-Z,.!? ]*){0,3} Repeat 0 - 3 times matching a single digit followed by optional listed chars (Again without a digit)
$ End of string
regex demo
If you don't want to match an empty string and a lookahead is supported:
^(?!$)[a-zA-Z,.!? ]*(?:\d[a-zA-Z,.!? ]*){0,3}$
See another regex demo
Here is my two cents:
^(?!(.*\d){4})[A-Za-z ,.!?\d]+$
See the online demo
^ - Start string anchor.
(?! - Open a negative lookahead.
( - Open capture group.
.*\d - Match anything other than newline up to a digit.
){4} - Close capture group and match it 4 times.
) - Close negative lookahead.
[A-Za-z ,.!?\d]+ - 1+ Characters from specified class.
$ - End string anchor.
I think it should cover what you described.
Assuming you mean <= 3 digits, this may be a naive one but how about
[ALLOWED_CHARS]*[0-9]?[ALLOWED_CHARS]*[0-9]?[ALLOWED_CHARS]*[0-9][ALLOWED_CHARS]*?
Fill [ALLOWED_CHARS] to whatever you define is not special character and nums.

Regex: Find last occurrence of digit pair

I'm trying to find the last match of a digit pair in some kinds of strings like these:
123f64swfW68F43
123f64swfW6843
123f64swfW6843sad
123f64swfW6843sa3d
In all of them the matching result should be 43. I tried my best and came to:
/(\d{2})(?!.*\d)/
But this works only for the first three strings.
Please note that I want to do this in one regular expression and without any further scripting.
Thanks for your help!
You may use
\d{2}(?!\d|.*\d{2})
See the regex demo. It basically means "match 2 consecutive digits that are not immediately followed with a digit and that not followed with any 2 consecutive digits anywhere to the right of those two digits".
Details
\d{2} - two digits
(?!\d|.*\d{2}) - that are not followed with a digit or with any two digits aftr any 0+ chars other than line break chars.
Alternatively, you may use
/.*(\d{2})/
and grab Group 1 value. See the regex demo. This regex means "match all text it can to the last two digits, and capture the two digits in a separate memory buffer".
Details
.* - any 0+ chars other than line break chars, as many as possible
(\d{2}) - Capturing group 1: two digits

use ultraedit find and replace Perl regex to insert colon into 4 digit time string

I have multiple 24-hour time strings through several files. For example, 1234, which I wish to replace with 12:34.
Finding them is easy, just \d\d\d\d, that I understand and it works. However, what replace string do I need. In other words, say xx:xx, what do I put in place of each x.
I've tried numbers of things to no avail. I'm obviously not understanding how I get it to remember the digits it found and to recall them in the replace string.
If in your example data 4 digits represent 24 hour time strings you could match 2 capturing groups between word boundaries to prevent a match with more then 4 digits. You can Adjust the word boundaries to your requirements.
Match
\b(\d{2})(\d{2})\b
Replace
group1:group2 \1:\2
Explanation
\b Match a word boundary
(\d{2}) Capture in a group 2 digits
(\d{2}) Capture in a group 2 digits
\b Match a word boundary
Note
Matching 4 digits does not verify a valid 24 hour time. You could match that using for example \b([01][0-9]|2[0-3])([0-5][0-9])\b and replace with \1:\2

Regex - matching while ignoring some characters

I am trying to write a regex to max a sequence of numbers that is 5 digits long or over, but I ignore any spaces, dashes, parens, or hashes when doing that analysis. Here's what I have so far.
(\d|\(|\)|\s|#|-){5,}
The problem with this is that this will match any sequence of 5 characters including those characters I want to ignore, so something like "#123 " would match. While I do want to ignore the # and space character, I still need the number itself to be 5 digits or more in order to qualify at a match.
To be clear, these would match:
1-2-3-4-5
123 45
2(134) 5
Bonus points if the matching begins and ends with a number rather than with one of those "special characters" I am excluding.
Any tips for doing this kind of matching?
If I understood requirements right you can use:
^\d(?:[()\s#-]*\d){4,}$
RegEx Demo
It always matches a digit at start. Then it is followed by 4 or more of a non-capturing group i.e. (?:[()\s#-]*\d) which means 0 or more of any listed special character followed by a digit.
So just repeat a digit, followed by any other sequence of allowed characters 5 or more times:
^(\d[()\s#-]*){5,}$
You can ensure it ends on a digit if you subtract one of the repetitions and add an explicit digit at the end:
^(\d[()\s#-]*){4,}\d$
You can suggest non-digits with \D so et would be something like:
(\d\D*){5,}
Here is a guide.