How to get 3 conditions all matching in a PHP regex? - php

I am trying to write a regex and matches 3 conditions, and would return true if all three conditions are met.
Condition 1) string starts with a "{"
Condition 2) string DOES NOT contain a space somewhere between brackets
Condition 3 string ends with a "}"
So far I have come up with ^{|[ ]|}$, which checks for a space. But I need to make it match if there are no spaces between the brackets. Also this will return true if the string starts with a { but doesn't end with a } and vise versa. I've been messing with regex101.com, but can't figure the no spaces portion out.
Could someone explain how to match if something does not exist in the string?

It seems you need
/^{\S*}$/
See the regex demo.
Details:
^ - start of string
{ - a literal {
\S* - 0+ chars other than whitespace
} - a literal }
$ - end of string.
For a general case, when you want to match if something DOES NOT exist in the string, you can bear in mind 2 approaches:
1) The string that should be absent is a single char: use either a negated character class (e.g., ^[^;]*$ will match a string that has no ; inside), or a "negative" shorthand character class (like here, \S is the reverse of \s and using ^\S*$ you match a string that has no whitespace)
2) The text that the string must not contain is a multicharacter string: then use lookarounds (e.g. the string should not contain like: ^(?!.*like).*$, or even ^(?!.*like)).

Related

Regex to validate the input rules

I want to validate using regex the user input to see if match the following rules.
Valid input:
2-000000000000
1-234342324342
...
Rules:
It has to be 13 digit numbers, no string.
Allow hyphen - come after the first character.
Allow space before and after the hyphen - character.
Here's what I tried in PHP, but still not correct:
if(preg_match("/[0-9?\-[0-9]/i])) {
echo "matched";
}
Note your double-quoted string literal is malformed, the closing " is missing.
Also, mind that [0-9?\-[0-9] is a malformed regex that matches a digit, ?, - or [ char. The i flag is irrelevant here, since there are no letters in the pattern.
I suggest using
preg_match("/^\d *- *\d{12}\z/", $string)
If the spaces can be any whitespace, replace the literal spaces with \s.
Note the use of \z anchor, I prefer it to $ in validation scenarios, since $ can match before the final line feed char in the string.
See the regex demo (\z replaced with $ since the input is a single multiline string there).

Explain the Regular Expression /^[a-zA-Z ]*/

I understand that the regex pattern must match a string which starts with the combination and the repetition of the following characters:
a-z
A-Z
a white-space character
And there is no limitation to how the string may end!
First Case
So a string such as uoiui897868 (any string that only starts with space, a-z or A-Z) matches the pattern... (Sure it does)
Second Case
But the problem is a string like 76868678jugghjiuh (any string that only starts with a character other than space, a-z or A-Z) matches too! This should not happen!
I have checked using the php function preg_match() too , which returns true (i.e. the pattern matches the string).
Also have used other online tools like regex101 or regexr.com. The string does match the pattern.
Can anybody could help me understand why the pattern matches the string described in the second case?
/^[a-zA-Z ]*/
Your regex will match strings that "begin with" any number (including zero) of letters or spaces.
^ means "start of string" and * means "zero or more".
Both uoiui897868 and 76868678jugghjiuh start with 0 or more letters/spaces, so they both match.
You probably want:
/^[a-zA-Z ]+/
The + means "one or more", so it won't match zero characters.
Your regex is completely useless: it will trivially match any string (empty, non-empty, with numbers, without,...), regardless of its structure.
This because
with ^, you enforce the begin of the string, now every string has a start.
You use a group [A-Za-z ], but you use a * operator, so 0 or more repititions. Thus even if the string does not contain (or begins with) a character from [A-Za-z ], the matcher will simply say: zero matches and parse the remaining of the string.
You need to use + instead of * to enforce "at least one character".
The '*' quantifier on the end means zero or more matches of the character, so all strings will match. Perhaps you want to drop the wildcard quantifier, or change it to a '+' quantifier, and add a '$' on the end to test the whole string.
What you really want is to match one or more of the preceding characters.
For that you use +
/^[a-zA-Z ]+/

Difference between regular expressions

I'm trying to work out what the differences are between these two:
preg_match('-^[^'.$inv.']+\.?$-' , $name
preg_match('-['.$inv.']-', $name
Thanks
To make it easier to exemplify, assume $inv = 'a'…
-^[^a]+\.?$- needs to match the whole string, because of the caret and the dollar signs. The string is expected to start with a character other than "a", followed by 0 or more characters that are still not "a"s. The last character in this string, however, can be a dot (hence the question mark after the dot)
-[a]- will match the first "a" in the string and it will stop looking as soon as it finds a match because you're using preg_match() and not preg_match_all().
Your first pattern does not make any sense, though, since already \. = [^a] (translated into English as: a dot is already not an "a")
[EDIT] The first pattern can actually mean something when there's a dot in the character class.
First of, be careful with $inv, depending on its content it could be possible to do some injections in the regular expression. To avoid that issue, use preg_quote().
That said, the first regex will be :
^ <-- the given string must begin with
[ <-- one of those characters
^ <-- inverse the accepted characters (instead of accepted characters, the following characters will be those that are not accepted)
$inv <-- characters
] <-- end of the list of characters (here not accepted characters)
+ <-- at least one character must be matched, more are accepted
\. <-- a '.'
? <-- the previous '.' isn't mandatory
$ <-- the given string must end here
If $inv = 'abc.' it will match:
def
def.
d
d.
It won't match:
., because the . isn't accepted by the [^abc.] group, even though there is \.? later, at least one character must be before a .
de.s, because the . isn't accepted in the [^abc.] group, it is only possible to have it at the end of the given string thanks to \.?
a
deb
testc
teskopkl;;[!##$b., because of the b
an empty string, at least one character must be matched with '[^'.$inv.']+'
It could be simplified into '^[^'.$inv.']+$' (don't forget the preg_quote though)
The second one will be:
[ <-- one of those characters
$inv <-- characters
] <-- end of the list of characters (here accepted characters)
If $inv = 'abc.' it will match
any string containing at least one of the letters a, b, c or .
It won't match any string which doesn't contain a, b, c or ..
In plain English, the first one is looking for an entire line which begins with one or more characters not included with the $inv string, and ending with an optional period.
The second one simply tries to match one character as specified by the value for $inv.
The first pattern matches a line containing none of the characters in $inv, optionally ending the line with a period.
The second pattern matches anything containing any of the characters in $inv.
- is the pattern delimiter, marking the beginning and end of the expression. It can technically be any character, but is most often /.
^ denotes the beginning of the string
[ ] encapsulates a set of characters to be matched
[^ ] encapsulates a set of characters that should not be matched, any other character is considered to be a match.
+ denotes that the previous character or set of characters should be matched one or more times.
. normally matches any character, which is why it is escaped as \. here to indicate a literal period character.
? denotes that the previous character should be matched zero or one time.
$ denotes the end of a string.
['.$inv.']
Lets go with the second one to begin with, since it's the simpler one.
This simply matches a string containing any single one of the characters contained within the string in the variable $inv.
It could contain anything else before or after that character from $inv.
^[^'.$inv.']+\.?$
Now the second one:
This matches a string that contains anything except the characters in $inv (the ^ inside the [] is a negative match).
The match that isn't part of $inv must be at the start of the string (the ^ outside the [] matches the start of the string).
The string can contain as many matching characters as it likes (one or more; that's the + sign after the [])
After that, it may optionally have a dot (the \.? is an optional dot character).
And nothing else after that (the $ matches the end of the string).
Note that in both cases, if $inv contains any regex reserved characters, it will fail (or do something unexpected). You should use preg_quote() to avoid this.
So... uh, they're completely different expressions. Not so much "what's the difference between them" as "what's the same about them". Answer: not much.
The first matches a string from start up to the first occurance of $inv followed by one or zero periods where the string must end.
The second matches a string only containing $inv.
Essentially they are almost the same, except the first allows for a possible . at the end.

Regex to match numbers, # # % signs

I am trying to write a regex that matches all numbers (0-9) and # # % signs.
I have tried ^[0-9#%#]$ , it doesn't work.
I want it to match, for example: 1234345, 2323, 1, 3#, %#, 9, 23743, #####, or whatever...
There must be something missing?
Thank you
You're almost right... All you're missing is something to tell the regular expression there may be more than once of those characters like a * (0 or more) or a + (1 or more).
^[0-9#%#]+$
The ^ and $ are used do indicate the start and end of a string, respectively. Make sure that you string only contains those characters otherwise, it won't work (e.g. "The number is 89#1" wouldn't work because the string begins with something other than 0-9, #, %, or #).
Your pattern ^[0-9#%#]$ only matches strings that are one character long. The [] construct matches a single character, and the ^ and $ anchors mean that nothing can come before or after the character matched by the [].
If you just want to know if the string has one of those characters in it, then [0-9#%#] will do that. If you want to match a string that must have at least one character in it, then use ^[0-9#%#]+$. The "+" means to match one or more of the preceding item. If you also want to match empty strings, then use [0-9#%#]*. The "*" means to match zero or more of the preceding item.
It should be /^[0-9#%#]+$/. The + is a qualifier that means "one or more of the preceding".
The problem with your current regex is that it will only match one character that could either be a number or #, %, or #. This is because the ^ and $ characters match the beginning and the end of the line respectively. By adding the + qualifier, you are saying that you want to match one or more of the preceding character-class, and that the entire line consists of one or more of the characters in the specified character-class.
remove the caret (^), it is used to match from the start of the string.
You forgot "+"
^[0-9#%#]+$ must work

PHP Regular Expression [accept selected characters only]

I want to accept a list of character as input from the user and reject the rest. I can accept a formatted string or find if a character/string is missing.
But how I can accept only a set of character while reject all other characters. I would like to use preg_match to do this.
e.g. Allowable characters are: a..z, A..Z, -, ’ ‘
User must able to enter those character in any order. But they must not allowed to use other than those characters.
Use a negated character class: [^A-Za-z-\w]
This will only match if the user enters something OTHER than what is in that character class.
if (preg_match('/[^A-Za-z-\w]/', $input)) { /* invalid charcter entered */ }
[a-zA-Z-\w]
[] brackets are used to group characters and behave like a single character. so you can also do stuff like [...]+ and so on
also a-z, A-Z, 0-9 define ranges so you don't have to write the whole alphabet
You can use the following regular expression: ^[a-zA-Z -]+$.
The ^ matches the beginning of the string, which prevents it from matching the middle of the string 123abc. The $ similarly matches the end of the string, preventing it from matching the middle of abc123.
The brackets match every character inside of them; a-z means every character between a and z. To match the - character itself, put it at the end. ([19-] matches a 1, a 9, or a -; [1-9] matches every character between 1 and 9, and does not match -).
The + tells it to match one or more of the thing before it. You can replace the + with a *, which means 0 or more, if you also want to match an empty string.
For more information, see here.
You would be looking at a negated ^ character class [] that stipulates your allowed characters, then test for matches.
$pattern = '/[^A-Za-z\- ]/';
if (preg_match($pattern, $string_of_input)){
//return a fail
}
//Matt beat me too it...

Categories