Insert - after every second Character - c#

so I'm developimg a Game with Unity 3D using C#. As first step the user has to enter his personal Code, which consists of 5 pairs, where each pairs has 2 characters/numbers (Im validating the characters & numbers separately). Now what I'm trying to achieve is that after every second character there should appear a minus, like you have after every 4th number, when you enter your credit-card number.
Example: 27-05-AB-CD-EF
So now I tried to use a Regular Expression and its working for the first two letters, but somehow the Regex does see the minus as a character too, and then it adds a minus infinitely often. I tried different versions, where i thought that i just allow letters and numbers, but somehow that doesn't work.
Regex.Replace(codeText, "([A-Za-z0-9][^-]){2}", "$0-");
Any guess what might be doing wrong?

Try with this expression "([A-Za-z0-9]){2}(?!-)" where (?!-) is a Zero-width negative lookahead assertion which in case you don't know is an expression that is matched but isn't part of the match value. So this expression matches two characters that aren't followed by -.
https://www.regular-expressions.info/lookaround.html read this page for more information

Related

Regex groups expression not capturing content

I'm trying to create a large regex expression where the plan is to capture 6 groups.
Is gonna be used to parse some Android log that have the following format:
2020-03-10T14:09:13.3250000 VERB CallingClass 17503 20870 Whatever content: this log line had (etc)
The expression I've created so far is the following:
(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{7})\t([A-Za-z]{4})\t(\w{+})\t(\d{5})\t(\d{5})\t(.*$)
The lines in this case are Tab separated, although the application that I'm developing will be dynamic to the point where this is not always the case, so regex I feel is still the best option even if heavier then performing a split.
Breaking down the groups in more detail from my though process:
Matches the date (I'm considering changing this to a x number of characters instead)
(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{7})
Match a block of 4 characters
([A-Za-z]{4})
Match any number of characters until the next tab
(\w{+})
Match a block of 5 numbers 2 times
\t(\d{5})
At last, match everything else until the end of the line.
\t(.*$)
If I use a reduced expression to the following it works:
(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{7})\t([A-Za-z]{4})\t(.*$)
This doesn't include 3 of the groups, the word and the 2 numbers blocks.
Any idea why is this?
Thank you.
The problem is \w{+} is going to match a word character followed by one or more { characters and then a final } character. If you want one or more word characters then just use plus without the curly braces (which are meant for specifying a specific number or number range, but will match literal curly braces if they do not adhere to that format).
(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{7})\t([A-Za-z]{4})\t(\w+)\t(\d{5})\t(\d{5})\t(.*$)
I highly recommend using https://regex101.com/ for the explanation to see if your expression matches up with what you want spelled out in words. However for testing for use in C# you should use something else like http://regexstorm.net/tester

Regular expression with only numbers, dots and minimum value

Im trying to make a regular expression that accept only numbers, dots and that has minimum value and max value.
E.g:
1.000 - valid
100.000 - valid
100.000a -not valid
.10 - not valid
100 - not valid
I have this, which works as i want with numbers and dots, only one thing is missing here, and that is minimum and maximum validation.
#"^([+-]?\d{1,3}(?:,\d{1,3})*(?:\.\d+)*)$"
PS:
Im using data annotations on .net core
Update
I have a javascript that separates users input in input field to thousand format like:
From: 1000000
To: 1.000.000
For better user experience.
But, the problem is the validation with data annotations.
With the RegularExpression i have above is working with the dots, i just need a minimum and maximum value.
I have tried with Range(min, max), but it recognise it as an invalid input because of the dots.
Regards
Given your comment I assume this is what your after:
^[+-]?[1-9]\d{0,2}(?:\.\d{3})+$
It matches a range of 1-3 digits (the first not being a 0), then followed by at least one (no upper limit) sequence of . + three digits.
This will match any number larger than one thousand with . as thousand separators. And since your attempt allowed it, this also allows an optional sign in the beginning.
See it in action here at regexstorm. Note! I can't get $ and multiline to work there so a \s is used instead to illustrate.
Considering that after every number there is space character in the string
This should do the job :
regex = #"[0-9]{1,3}\.[0-9]{1,5}"
Update :
As the obtained text will be numbers , so you could simply validate them for a range check .
For reference please have a look :regex reference
Let me know , if it doesn't works

Regex pattern for validation - trying to condense repetitive patterns in regex

I have to validate a "project code" string in C# - the string length can be anywhere between 5-10 characters. The only rules outside this are as follows:
First character can only be a letter or number
Middle characters if they exist can be letter, number or a period (.)
Last character can only be a letter or number
*Avoid more than one period in a row in the middle
I can validate the 5-10 characters restriction like this:
^(?=.{5,10}$)
And part 1 and part 3 like this:
[a-zA-Z0-9]{1}
The middle rule is looking like this:
[a-zA-Z0-9.]{0,8}
And if I put it all together I have this:
^(?=.{5,10}$)[a-zA-Z0-9]{1}[a-zA-Z0-9.]{0,8}[a-zA-Z0-9]{1}$
It works fine, but with all that nearly identical code, it seems it could be condensed somehow. Any ideas? Thanks!
You can make it a bit shorter by matching the middle part 3 to 8 times, and a single time with the outer parts (You don't need {1}). This eliminates the need for the 5,10 part of your code because 1+3+1=5 and 1+8+1=10.
^[a-zA-Z0-9][a-zA-Z0-9.]{3,8}[a-zA-Z0-9]$
You can use
(?i)^(?!.*[.]{2})[a-z0-9][a-z0-9.]{3,8}[a-z0-9]$
See demo
^[a-z0-9] - First character can only be a letter or number
[a-z0-9.]{3,8} - Middle characters if they exist can be letter, number or a period (.)
[a-z0-9]$ - Last character can only be a letter or number
^(?!.*[.]{2}) - *Avoid more than one period in a row in the middle
The (?i) inline modifier can be replaced with RegexOptions.IgnoreCase flag when used with the new Regex() initializer.
I'm going to piggy-back off Cyral's answer so +1 to him!
I'm using a case insensitive flag to get from [a-zA-Z0-9] to [a-z0-9]
^(?i)[a-z0-9][a-z0-9.]{3,8}[a-z0-9]$
Thanks folks!

Regular expression for adding special character to phone number

I have added the following regular expression for validating a mobile phone number:
(^07[1,2,3,4,5,7,8,9][0-9]{7,8}$)
I want to allow the user to enter a # character too and I'm not sure where to fit it in. They may need to enter # character after they have dialed a number, or at the beginning of a number to dial a direct number or an extension.
First, your current regex matches 'numbers' of the format 07,12345678 as well. So you need to change [1,2,3,4,5,7,8,9] to [1-9] (when you have a - between two characters in a character class, it usually means that there's a range)
If you want to accept an optional # character, you can use the ? quantifier which means 0 or 1 times.
^#?07[1-9][0-9]{7,8}#?$
regex101 demo
Except that, as you can see in the demo, it will also match numbers with two hashes; one at the front and one at the end. One option to circumvent this is to use some conditionals (which C# can support).
^(#)?07[1-9][0-9]{7,8}(?(1)|#?)$
regex101 demo
(?(1)|#?) basically means that if the first hash was matched, then nothing more should be matched. Otherwise, if no hash was initially matched, then it can match a hash, if there is one at the end of the number.
In C#, it will be a bit like this:
Regex.Match(myString, #"^(#)?07[1-9][0-9]{7,8}(?(1)|#?)$");
Or you could use a negative lookahead to make sure there's never more than one hash in the number:
^(?!.*#.*#.*$)#?07[1-9][0-9]{7,8}#?$

Assist me on building my own regex

I'm completely new in this area, I need a regex that follows these rules:
Only numbers and symbols are allowed.
Must start with a number and ends with a number.
Must not contain more than 1 symbol in a row. (for example 123+-4567 is not accepted but 12+345-67 is accepted.
I tried ^[0-9]*[+-*/][0-9]*$ but I think it's a stupid try.
You were close with your attempt. This one should work.
^[0-9]+([+*/-][0-9]+)*$
explanation:
^ matches beginning of the string
[0-9]+ matches 1 or more digits.
[+*/-] matches one from specified symbols
([+*/-][0-9]+)* matches group of symbol followed by at least one digit, repeated 0 or more times
$ matches end of string
We'll build that one from individual parts and then we'll see how we can be smarter about that:
Numbers
\d+
will match an integer. Not terribly fancy, but we need to start somewhere.
Must start with a number and end with a number:
^\d+.*\d+$
Pretty straightforward. We don't know anything about the part in between, though (also the last \d+ will only match a single digit; we might want to fix that eventually).
Only numbers and symbols are allowed. Depending on the complexity of the rest of the regex this might be easier by explicitly spelling it out or using a negative lookahead to make sure there is no non-(number|symbol) somewhere in the string. I'll go for the latter here because we need that again:
(?!.*[^\d+*/-])
Sticking this to the start of the regex makes sure that the regex won't match if there is any non-(number|symbol) character anywhere in the string. Also note that I put the - at the end of the character class. This is because it has a certain special meaning when used between two other characters in a character class.
Must not contain more than one symbol in a row. This is a variation on the one before. We just make sure that there never is more than one symbol by using a negative lookahead to disallow two in sequence:
(?!.*[+/*-]{2})
Putting it all together:
(?!.*[^\d+*/-])(?!.*[+/*-]{2})^\d+.*\d+$
Testing it:
PS Home:\> '123+-4567' -match '(?!.*[^\d+*/-])(?!.*[+/*-]{2})^\d+.*\d+$'
False
PS Home:\> '123-4567' -match '(?!.*[^\d+*/-])(?!.*[+/*-]{2})^\d+.*\d+$'
True
However, I only literally interpreted your rules. If you're trying to match arithmetic expressions that can have several operands and operators in sequence (but without parentheses), then you can approach that problem differently:
Numbers again
\d+
Operators
[+/*-]
A number followed by an operator
\d+[+/*-]
Using grouping and repetition to match a number followed by any number of repetitions of an operator and another number:
\d+([+/*-]\d+)*
Anchoring it so we match the whole string:
^\d+([+/*-]\d+)*$
Generally, for problems where it works, this latter approach works better and leads to more understandable expressions. The former approach has its merits, but most often only in implementing password policies (apart from »cannot repeat any of your previous 30689 passwords«).

Categories

Resources