simple preg_match not returning expected results - php

I went through a few basics on preg match but its quite difficult when your new to it.
What im trying to do is search for this instance in a string
bug1234
it shouldnt be case sensitive so bug1234 or BuG1234 should work
it must be the word bug followed by any 4 numbers
there should be no spaces or anything in between bug1234 so bug-1234 should not be a match
it should ignore things like bug1234z and abug1234 so it must be bug1234 with nothing prefixing it or coming directly after it unless there is a space between then so "there is a problem with bug1234 that i cant solve" would be a match.
Just to clarify it can be any number not 1234 specifically but they must be 4 digits
Heres my lame attempt:
$file_string = $workdetails->text;
$file_string = strtolower($file_string);
$bugkey = "/bug[0-9]{4}/";
$nosey = preg_match($bugkey, $file_string);
if($nosey !== false)
{
echo "We have a match baby!!"
}
That just seemed to return all sorts, empty string,s string with no mention of the word bug

Try changing the regex to:
/\bbug[0-9]{4}\b/i
The \b modifier will only match on a word boundary so that makes sure it doesn't match things like abug1234, bug12345 or bug1234was bad. I also added the i modifier so it is case insensitive. You no longer need to use strtolower.
Also, preg_match typically returns an integer, and returns (int)0 if there is no match. It only returns FALSE on failure. Therefore you should change the match check to be:
if ($nosey > 0) {
// or just
if ($nosey) {

Try it with:
preg_match('/\b(bug\d{4})/i', $file_string, $match);
print_r($match);
The modifier i stands for case insensitive and the \b is for a whole word only (word boundary).

Try this: /(?ism)bug(?i-sm)[0-9]{4}/
Tested on the Regular Expression Test Tool
With data:
sdfsfsbUG1234cccs
Cheers!

Related

PHP preg_match regular expression for find date in string

I try to make system that can detect date in some string, here is the code :
$string = "02/04/16 10:08:42";
$pattern = "/\<(0?[1-9]|[12][0-9]|3[01])\/\.- \/\.- \d{2}\>/";
$found = preg_match($pattern, $string);
if ($found) {
echo ('The pattern matches the string');
} else {
echo ('No match');
}
The result i found is "No Match", i don't think that i used correct regex for the pattern. Can somebody tell me what i must to do to fix this code
First of all, remove all gibberish from the pattern. This is the part you'll need to work on:
(/0?[1-9]|[12][0-9]|3[01]/)
(As you said, you need the date only, not the datetime).
The main problem with the pattern, that you are using the logical OR operators (|) at the delimiters. If the delimiters are slashes, then you need to replace the tube characters with escaped slashes (/). Note that you need to escape them, because the parser will not take them as control characters. Like this: \/.
Now, you need to solve some logical tasks here, to match the numbers correctly and you're good to go.
(I'm not gonna solve the homework for you :) )
These articles will help you to solve the problem tough:
Character classes
Repetition opetors
Special characters
Pipe character (alternation operator)
Good luck!
In your comment you say you are looking for yyyy, but the example says yy.
I made a code for yy because that is what you gave us, you can easily change the 2 to a 4 and it's for yyyy.
preg_match("/((0|1|2|3)[0-9])\/\d{2}\/\d{2}/", $string, $output_array);
Echo $output_array[1]; // date
Edit:
If you use this pattern it will match the time too, thus make it harder to match wrong.
((0|1|2|3)[0-9])/\d{2}/\d{2}\s+\d{2}:\d{2}:\d{2}
http://www.phpliveregex.com/p/fjP
Edit2:
Also, you can skip one line of code.
You first preg_match to $found and then do an if $found.
This works too:
If(preg_match($pattern, $string, $found))}{
Echo $found[1];
}Else{
Echo "nothing found";
}
With pattern and string as refered to above.
As you can see the found variable is in the preg_match as the output, thus if there is a match the if will be true.

Correct regex for this pattern

I've got some issues understanding this regex.
I tried doing a pattern but does not work like intended.
What I want is [A-Za-z]{2,3}[0-9]{2,30}
That is 2-3 letters in the beginning and 2-30 numbers after that
FA1321321
BFA18098097
I want to use it to validate an input field but can't figure out how the regex should look like.
Can any one that can help me out even explain a bit about it?
Your regex is correct - just make sure to surround it with / in PHP, and perhaps ^, $ if you want it to strictly match the entire string (no extra characters before/after).
$pattern = "/^[A-Za-z]{2,3}[0-9]{2,30}$/"
$found = preg_match($pattern, $your_str);
From the PHP documentation:
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.

PHP Reverse Preg_match [duplicate]

This question already has answers here:
Regular expression to match a line that doesn't contain a word
(34 answers)
Closed 4 years ago.
if(preg_match("/" . $filter . "/i", $node)) {
echo $node;
}
This code filters a variable to decide whether to display it or not. An example entry for $filter would be "office" or "164(.*)976".
I would like to know whether there is a simple way to say: if $filter does not match in $node. In the form of a regular expression?
So... not an "if(!preg_match" but more of a $filter = "!office" or "!164(.*)976" but one that works?
This can be done if you definitely want to use a "negative regex" instead of simply inverting the result of the positive regex:
if(preg_match("/^(?:(?!" . $filter . ").)*$/i", $node)) {
echo $node;
}
will match a string if it doesn't contain the regex/substring in $filter.
Explanation: (taking office as our example string)
^ # Anchor the match at the start of the string
(?: # Try to match the following:
(?! # (unless it's possible to match
office # the text "office" at this point)
) # (end of negative lookahead),
. # Any character
)* # zero or more times
$ # until the end of the string
The (?!...) negative assertion is what you're looking for.
To exclude a certain string from appearing anywhere in the subject you can use this double assertion method:
preg_match('/(?=^((?!not_this).)+$) (......)/xs', $string);
It allows to specify an arbitrary (......) main regex still. But you could just leave that out, if you only want to forbid a string.
Answer number 2 by mario is the correct answer, and here is why:
First to answer the comment by Justin Morgan,
I'm curious, do you have any idea what the performance of this would
be as opposed to the !preg_match() approach? I'm not in a place where
I can test them both. – Justin Morgan Apr 19 '11 at 21:53
Consider the gate logic for a moment.
When to negate preg_match(): when looking for a match and you want the condition to be 1)true for the absence of the desired regex, or 2)false for the regex being present.
When to use negative assertion on the regex: when looking for a match and you want the condition to be true if the string ONLY matches the regex, and fail if anything else is found. This is necessary if you really need to test for undesireable characters while allowing ommission of permitted characters.
Negating the result of (preg_match() === 1) only tests if the regex is present. If 'bar' is required, and numbers aren't allowed, the following won't work:
if (preg_match('bar', 'foo2bar') === 1) {
echo "found 'bar'"; // but a number is here, so fail.
}
if (!pregmatch('[0-9]', 'foobar') === 1) {
echo "no numbers found"; // but didn't test for 'bar', so fail.
}
So, in order to really test multiple regexes, a beginner would test using multiple preg_match() calls... we know this is a very amateur way to do it.
So, the Op wants to test a string for possible regexes, but the conditional may only pass as true if the string contains at least one of them. For most simple cases, simply negating preg_match() will suffice, but for more complex or extensive regex patterns, it won't. I will use my situation for a more real-life scenario:
Say you want to have a user form for a person's name, particularly a last name. You want your system to accept all letters regardless of case and placement, accept hyphens, accept apostrophes, and exclude all other characters. We know that matching a regex for all undesired characters is the first thing we think of, but imagine you are supporting UTF-8... that's alot of characters! Your program will be nearly as big as the UTF-8 table just on a single line! I don't care what hardware you have, your server application has a finite limit on how long a command be, not to mention the limit of 200 parenthesized subpatterns, so the ENTIRE UTF-8 character table (minus [A-Z],[a-z],-,and ') is too long, never mind that the program itself will be HUGE!
Since we won't use an if (!preg_match('.#\\$\%... this can be quite long and impossible to evaluate... on a string to see if the string is bad, we should instead test the easier way, with an assertion negative lookaround on the regex, then negate the overall result using:
<?php
$string = "O'Reilly-Finlay";
if (preg_match('/?![a-z\'-]/i', $string) === 0) {
echo "the given string matched exclusively for regex pattern";
// should not work on error, since preg_match returns false, which is not an int (we tested for identity, not equality)
} else {
echo "the given string did not match exclusively to the regex pattern";
}
?>
If we only looked for the regex [a-z\'-]/i , all we say is "match string if it contains ANY of those things", so bad characters aren't tested. If we negated at the function, we say "return false if we find a match that contained any of these things". This isn't right either, so we need to say "return false if we match ANYTHING not in the regex", which is done with lookahead. I know the bells are going off in someone's head, and they are thinking wildcard expansion style... no, lookahead doesn't do this, it just does negation on each match, and continues. So, it checks first character for regex, if it matches, it moves on until it finds a non-match or the end. After it finishes, everything that was found to not match the regex is returned to the match array, or simply returns 1. In short, assert negative on regex 'a' is the opposite of matching regex 'b', where 'b' contains EVERYTHING ELSE not matchable by 'a'. Great for when 'b' would be ungodly extensive.
Note: if my regex has an error in it, I apologize... I have been using Lua for the last few months, so I may be mixing my regex rules. Otherwise, the '?!' is proper lookahead syntax for PHP.

Regular expression problems

I can't get the preg_match to find a word anywhere a the string.
I have this:
$bad_words = "/(\bsuck\b)|(\bsucks\b)|(\bporn\b)|";
$text = "sucky";
if(preg_match($bad_term_filter, trim($feedback_review_comment)) != 0 )
I need to return true but it only returns true if its an exact match, for example if
$text = "suck";
that returns true
\b is the word boundary anchor. It looks like you're trying to find if some word occurs anywhere regardless of the word boundaries, so I think the pattern you want is simply:
suck|porn
You also do not want the last empty alternate, because that will match everything (all string contains an empty string). There is no need to explicitly look for sucks, because it already contains suck.
References
regular-expressions.info/Anchors and Character Classes, and Optional

RegEx in PHP: find the first matching string

I want to find the first matching string in a very very long text. I know I can use preg_grep() and take the first element of the returned array. But it is not efficient to do it like that if I only need the first match (or I know there is exactly only one match in advance). Any suggestion?
preg_match() ?
preg_match() returns the number of
times pattern matches. That will be
either 0 times (no match) or 1 time
because preg_match() will stop
searching after the first match.
preg_match_all() on the contrary will
continue until it reaches the end of
subject. preg_match() returns FALSE if
an error occurred.
Here's an example of how you can do it:
$string = 'A01B1/00asdqwe';
$pattern = '~^[A-Z][0-9][0-9][A-Z][0-9]+~';
if (preg_match($pattern, $string, $match) ) {
echo "We have matched: $match[0]\n";
} else {
echo "Not matched\n";
}
You can try print_r($match) to check the array structure and test your regex.
Side note on regex:
The tilde ~ in the regex are just delimiters needed to wrap around
the pattern.
The caret ^ denote that we are matching from the start
of the string (optional)
The plus + denotes that we can have one or
more integers that follow. (So that A01B1, A01B12, A01B123 will also
be matched.

Categories