Okay, I am a noob to regex, and I am using this site for my regex primer:
Question: using the s modifier, the code below is suppose to echo 4 as it has found 4 newline characters.
However, when I run this I get one(1), why?
link text
<?php
/*** create a string with new line characters ***/
$string = 'sex'."\n".'at'."\n".'noon'."\n".'taxes'."\n";
/*** look for a match using s modifier ***/
echo preg_match("/sex.at.noon/s", $string, $matches);
/*The above code will echo 4 as it has found 4 newline characters.*/
?>
Use preg_match_all() instead which doesn't stop after the first 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. —PHP.net
However, the code will output still only 1 because what you are matching is the regex "sex.at.noon" and not a line break.
preg_match() will only ever return 0 or 1 because it stops after the first time the pattern matches. If you use preg_match_all() it will still return 1 because your pattern only matches once in the string you're matching against.
If you want the number of newlines via regex:
echo preg_match_all("/\n/m", $string, $matches);
Or via string functions:
echo substr_count($string, "\n");
Related
I wanted to count asterisks from a string starting with foo 'fooarbazlujabazlewis*bazbazlewbaz' and i should be able to count asterisk from another string starting with luja in short I wanted the starting string to be changed programmatically
I tried below code, but it counts any asterisk even if foo is not at the beginning
preg_match_all('/(^foo\*)*(\*)/', '*foo*arbaz*luj*abaz*lewis*bazbazlewbaz');
the result is 6. but in this case, I wanted it to fail since foo is not at the beginning.
It is not the best application for a regex, but you can use
preg_match_all('~(?:\G(?!\A)|^foo)[^*]*\K\*~', $string, $matches)
See the regex demo. Details:
(?:\G(?!\A)|^foo) - either the end of the previous successful match or foo at the start of string
[^*]* - zero or more chars other than *
\K - discard the text matched so far
\* - an asterisk.
See the PHP demo:
$string = "foo*arbaz*luj*abaz*lewis*bazbazlewbaz";
echo preg_match_all('~(?:\G(?!\A)|^foo)[^*]*\K\*~', $string, $matches);
// => 5
Without a regex, you could simply check if foo appears at the start of string (using strpos) and then use substr_count to count the occurrences of asterisks:
$string = "foo*arbaz*luj*abaz*lewis*bazbazlewbaz";
if (strpos($string, "foo") === 0 ) {
echo substr_count($string, "*");
}
See this PHP demo.
This question already has answers here:
How to use preg_match to extract data?
(5 answers)
Closed 8 years ago.
I'm working with an API where I receive error messages such as:
{"message":"Contact is suppressed. ERROR_CONTACT_SUPPRESSED"}
I'm trying to take these error messages and just translate them into some sort of value or code so that I can provide good responses to the user rather than just a generic error.
The only thing in the error I can see that is always true is that the last portion is capitalised. Such as ERROR_CONTACT_SUPPRESED or ERROR_CONTACT_INVALID.
I know that preg_match can be used to get the uppercase characters but I believe they also have to be within a certain order/number of chars from the beginning or the end. How can I get only the capitalised section back?
I found the following but just got a result of 0 which is obviously incorrect
$result = preg_match("/^([A-Z]+)/", $result);
echo $result . '<br />';
Use this:
if(preg_match('/[A-Z_]*/', $string, $matches)) {
var_dump($matches);
}
Please read the documentation of preg_match. The function does not return the matched string as you may have expected:
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
Try this:
if(preg_match('/[A-Z_]+[^a-z]/', $string, $matches)) {
var_dump($matches);
}
It will ignore capitalised letters at the beginning of words.
Try using preg_match this way:
$str = '{"message":"Contact is suppressed. ERROR_CONTACT_SUPPRESSED"}';
preg_match("/([A-Z_]+)(?=\")/", $str, $match);
echo $result = $match[0] . '<br />';
The reason the pattern didn't match before was mainly because you indicated to match [A-Z] at the beginning of the line, which it wasn't =! (^[A-Z]). You also need to indicate the other characters present, which would include the underscore.
how would I avoid that the following :
$_SESSION['myVar']=preg_match("[^a-zA-Z]",'',$_SESSION['myVar']);
echo $_SESSION['myVar'];
displays
0
and instead it displays/outputs the var content ? preg_match gives out mixed type, but this shouldnt be the problem...
Why, is the value of the string itself not addressable with echo (by comapring its contents, it is OK)?
Formerly I had
$_SESSION['myVar']=ereg_replace("[^a-zA-Z]",'',$_SESSION['myVar']);
ant the output óf ereg_replace was correctly displayed the variable content.
PCRE in PHP need delimiters [docs] and you probably want preg_replace [docs]:
preg_replace("/[^a-zA-Z]/",'',$_SESSION['myVar']);
Assuming you had preg_replace, even then, the brackets ([...]) would be interpreted as delimiters and so the engine would literally try to match a-zA-Z at the beginning of the string and would not interpret the constructor as character class.
preg_match returns an int, not mixed: http://php.net/manual/en/function.preg-match.php
Use the matches parameter to get your matches.
The problem is that preg_match returns a Boolean, 1 if the pattern was matched, 0 if it didn't. preg_match simply matches occurrences, it doesn't replace them. Here's how you use preg_match:
$matched = array();
preg_match("/[^a-zA-Z]/", $_SESSION["myVar"], $matches);
print_r($matches); // All matches are in the array.
I have a preg match statement, and it checks for matches, but I was wondering how you can count the matches. Any advice appreciated.
$message='[tag] [tag]';
preg_match('/\[tag]\b/i',$message);
for example a count of this message string should lead to 2 matches
$message='[tag] [tag]';
echo preg_match_all('/\\[tag\\](?>\\s|$)/i', $message, $matches);
gives 2. Note you cannot use \b because the word boundary is before the ], not after.
See preg_match_all.
preg_match already returns the number of times the pattern matched.
However, this will only be 0 or 1 as it stops after the first match. You can use preg_match_all instead as it will check the entire string and return the total number of matches.
You should use preg_match_all if you want to match all occurences. preg_match_all returns number of matches. preg_match returns only 0 or 1, because it matches only once.
I think you need preg_match_all. It returns the number of matches it finds. preg_match stops after the first one.
You could use T-Regx library with count() method (and even automatic delimiters):
$count = pattern('\[tag]\b', 'i')->match('[tag] [tag]')->count();
$count // 2
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.