what is equivalent of =~ of ruby in php? - php

I am a Rubyist trying to implement some of my code in PHP and not able to get the equivalent PHP code for this particular def.Can anyone help me out.Thanks in advance.
def check_condition(str)
str =~ SOME_REGEX
end

In PHP it looks like:
function check_condition($str) {
return preg_match(SOME_REGEX, $str);
}
Unfortunately there is no regex-match operator in PHP unlike some other languages. You'll have to call a function. Follow the manual of preg_match() and the manual page about the so called perl compatible regular expresssions (preg) in general.
Something additional. After reading the manual page of preg_match you know that the method returns an integer, the number of matches found. As the method returns after the first match this can be only 0 or 1. As of the loose typing system of PHP this would be good for using it in loose comparisons like:
if(check_condition($str)) { ....
if(check_condition($str) == true) { ...
But it would not work in a strict comparison:
if(check_condition($str) === true) { ...
Therefore it would be a good idea to cast the return value of preg_match:
function check_condition($str) {
return (boolean) preg_match(SOME_REGEX, $str);
}
Update
I have thought a little bit about my last suggestion and I see a problem with this. preg_match() will return an integer if all is working fine but boolean FALSE if an error occurs. For example because of a syntax error in the regex pattern. Therefore you will be not aware of errors if you are just casting to boolean. I would use exceptions to show that an error was happening:
function check_condition($str) {
$ret = preg_match(SOME_REGEX, $str);
if($ret === FALSE) {
$error = error_get_last();
throw new Exception($error['message']);
}
return (boolean) $ret;
}

Have a look at preg_match:
if (preg_match('/regex/', $string) {
return 1;
}

Isn't it preg_match?
function check_condition($str) {
return preg_match(SOME_REGEX,$str);
}

I don't think there is an equivalent.
preg_match returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
=~however returns the position where the match starts, or nil if there is no match. Since nil is false and all numbers including zero are true, boolean operations are possible.
puts "abcdef" =~ /def/ #=> 3 # don't know how to get this from a RegExp in PHP
puts "Matches" if "abcdef"=~ /def/ #=> Matches

Related

exact preg_match with #

How can I preg_match exactly with that kind of search:
My value to find: #5#
My value to search: #5#;#9#
I did a simple
if (preg_match("#5#", "#5#;#9#")) { return true; } else { return false; }
And, it returns true.
The problem with that code, it's return also true if my value to compare is #51#;#55# whereas it has to be false in that case:
if (preg_match("#5#", "#51#;#55#")) { return true; } else { return false; }
Also returns true whereas I want false.
preg_match("#5#", "#51#;#55#") returns true because preg_match uses # as delimiter. In order to match #5# you have to add delimiters around the regex:
if (preg_match("/#5#/", "#51#;#55#")) { return true; } else { return false; }
This will return false.
If all you need is to find a string you know (#5#) in another string then the best way is to use function strpos(). It returns the boolean FALSE if it cannot find the string or an integer number that represents the position of the searched string into the other string.
It is faster that any preg_*() function.
$pos = strpos('#5#', '#5#;#9#');
if ($pos !== FALSE) {
echo('Found (at position '.$pos.')');
} else {
echo('Not found.');
}
You have to pay attention to the comparison operator: using $pos != FALSE is not enough because 0 == FALSE. You have to compare using === or !== to avoid this.
Using preg_match()
Your approach failed because in PHP the PCRE functions interpret the first character from the regex as a delimiter.
This means the regex in #5# is: 5. And this regex, of course, matches any 5 it finds in the string. To fix it you have to surround your regex with some delimiter (/ is usually used):
return preg_match('/#5#/', '#5#;#9#');

How to disable ' - ; : ~ ` from input and remove from string?

I tried to add extra security by removing special characters. I want to allow letters, numbers and ? = & only.
I tried:
if (strpos($_SERVER['REQUEST_URI'],'\'')) { echo 'true'; }
I cannot just simply put ' in between the '' as it breaks it so I tried adding the \ but it didn't work.
Is there a way to detect all the symbols in the url string or input field?
EDIT:
tried adding < simply into the list
if (preg_match('#[#*,!$\'\-;:<>~`^|\(\\)\\{\\}\\[\\]]#i', $_SERVER['REQUEST_URI']) || strpos($_SERVER['REQUEST_URI'],'script')) {
echo 'Cannot do that';
}
I tried adding ([\<])([^\>]{1,})*([\>]) into there but it didn't work.
I also tried adding a condition if strcmp($_SERVER['REQUEST_URI'], strip_tags($_SERVER['REQUEST_URI'])) != 0
and when i added into the url, it didn't do anything
Use preg_match to test for anything but the characters you want:
if (preg_match('#[^a-z0-9?=&]#i', $str)) { echo 'true'; }
Use preg_replace to remove them:
$str = preg_replace('#[^a-z0-9?=&]#i', '', $str);
If you just want to prohibit certain characters, use a regular expression that just matches those characters:
if (preg_match('#[\'\-;:~`]#i', $str)) { echo 'true'; }
You can fix that using double quotes as strings delimiter, try this
if (strpos($_SERVER['REQUEST_URI'],"'")) { echo 'true'; }
One thing that none of the posts addressed is why strpos didn't work for you. strpos can return two types. It can return an integer that is greater than or equal to zero. 0 being the first character. It can also return a boolean type false. To check if if strpos found a match it would have to have been written like this:
if (strpos($_SERVER['REQUEST_URI'],'\'') !== false) { echo 'true'; }
From the PHP Documentation The comparison $a !== $b operator works this way:
return TRUE if $a is not equal to $b, or they are not of the same type.
Information on strpos returning two types (boolean false or an integer) can be found in this PHP strpos Documentation. In particular:
Returns the position of where the needle exists relative to the beginning of the haystack string (independent of offset). Also note that string positions start at 0, and not 1.
Returns FALSE if the needle was not found.
So as you can see 0 and false are not the same thing which is why your test failed.
As for security and strings in PHP I recommend you look at this StackOverflow article for some opinions on the matter.

If string contains forward slash

How do i make a if statement which checks if the string contains a forward slash?
$string = "Test/Test";
if($string .......)
{
mysql_query("");
}
else
{
echo "the value contains a invalid character";
}
You can use strpos, which will make sure there is a forward slash in the string but you need to run it through an equation to make sure it's not false. Here you can use strstr(). Its short and simple code, and gets the job done!
if(strstr($string, '/')){
//....
}
For those who live and die by the manual, when the haystack is very large, or the needle is very small, it is quicker to use strstr(), despite what the manual says.
Example:
Using strpos(): 0.00043487548828125
Using strstr(): 0.00023317337036133
if(strpos($string, '/') !== false) {
// string contains /
}
From the PHP manual of strstr:
Note:
If you only want to determine if a particular needle occurs within
haystack, use the faster and less memory intensive function strpos()
instead.
Use strpos()
If it doesn't return false, the character was matched.
I compared strpos() results with 0. Somehow comparison with false did not work for me.
if (strpos($t, '/') !== 0) {
echo "No forward slash!";
}

Check if a string does not contains a specific substring [duplicate]

This question already has answers here:
How do I check if a string contains a specific word?
(36 answers)
Closed 26 days ago.
In SQL we have NOT LIKE %string%
I need to do this in PHP.
if ($string NOT LIKE %word%) { do something }
I think that can be done with strpos()
But can’t figure out how…
I need exactly that comparission sentence in valid PHP.
if ($string NOT LIKE %word%) { do something }
if (strpos($string, $word) === FALSE) {
... not found ...
}
Note that strpos() is case sensitive, if you want a case-insensitive search, use stripos() instead.
Also note the ===, forcing a strict equality test. strpos CAN return a valid 0 if the 'needle' string is at the start of the 'haystack'. By forcing a check for an actual boolean false (aka 0), you eliminate that false positive.
Use strpos. If the string is not found it returns false, otherwise something that is not false. Be sure to use a type-safe comparison (===) as 0 may be returned and it is a falsy value:
if (strpos($string, $substring) === false) {
// substring is not found in string
}
if (strpos($string, $substring2) !== false) {
// substring2 is found in string
}
use
if(stripos($str,'job')){
// do your work
}
<?php
// Use this function and Pass Mixed string and what you want to search in mixed string.
// For Example :
$mixedStr = "hello world. This is john duvey";
$searchStr= "john";
if(strpos($mixedStr,$searchStr)) {
echo "Your string here";
}else {
echo "String not here";
}
Kind of depends on your data, doesn't it? strpos('a foolish idea','fool') will show a match, but may not be what you want. If dealing with words, perhaps
preg_match("!\b$word\b!i",$sentence)
is wiser. Just a thought.

How can I validate regex?

I'd like to test the validity of a regular expression in PHP, preferably before it's used. Is the only way to do this actually trying a preg_match() and seeing if it returns FALSE?
Is there a simpler/proper way to test for a valid regular expression?
// This is valid, both opening ( and closing )
var_dump(preg_match('~Valid(Regular)Expression~', '') === false);
// This is invalid, no opening ( for the closing )
var_dump(preg_match('~InvalidRegular)Expression~', '') === false);
As the user pozs said, also consider putting # in front of preg_match() (#preg_match()) in a testing environment to prevent warnings or notices.
To validate a RegExp just run it against null (no need to know the data you want to test against upfront). If it returns explicit false (=== false), it's broken. Otherwise it's valid though it need not match anything.
So there's no need to write your own RegExp validator. It's wasted time...
I created a simple function that can be called to checking preg
function is_preg_error()
{
$errors = array(
PREG_NO_ERROR => 'Code 0 : No errors',
PREG_INTERNAL_ERROR => 'Code 1 : There was an internal PCRE error',
PREG_BACKTRACK_LIMIT_ERROR => 'Code 2 : Backtrack limit was exhausted',
PREG_RECURSION_LIMIT_ERROR => 'Code 3 : Recursion limit was exhausted',
PREG_BAD_UTF8_ERROR => 'Code 4 : The offset didn\'t correspond to the begin of a valid UTF-8 code point',
PREG_BAD_UTF8_OFFSET_ERROR => 'Code 5 : Malformed UTF-8 data',
);
return $errors[preg_last_error()];
}
You can call this function using the follow code :
preg_match('/(?:\D+|<\d+>)*[!?]/', 'foobar foobar foobar');
echo is_preg_error();
Alternative - Regular Expression Online Tester
RegExr
PHP Regular Expression Tester
Regular Expression Tool
If you want to dynamically test a regex preg_match(...) === false seems to be your only option. PHP doesn't have a mechanism for compiling regular expressions before they are used.
Also you may find preg_last_error an useful function.
On the other hand if you have a regex and just want to know if it's valid before using it there are a bunch of tools available out there. I found rubular.com to be pleasant to use.
You can check to see if it is a syntactically correct regex with this nightmare of a regex, if your engine supports recursion (PHP should).
You cannot, however algorithmically tell if it will give the results you want without running it.
From: Is there a regular expression to detect a valid regular expression?
/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/
Without actually executing the regex you have no way to be sure if it's be valid. I've recently implemented a similar RegexValidator for Zend Framework. Works just fine.
<?php
class Nuke_Validate_RegEx extends Zend_Validate_Abstract
{
/**
* Error constant
*/
const ERROR_INVALID_REGEX = 'invalidRegex';
/**
* Error messages
* #var array
*/
protected $_messageTemplates = array(
self::ERROR_INVALID_REGEX => "This is a regular expression PHP cannot parse.");
/**
* Runs the actual validation
* #param string $pattern The regular expression we are testing
* #return bool
*/
public function isValid($pattern)
{
if (#preg_match($pattern, "Lorem ipsum") === false) {
$this->_error(self::ERROR_INVALID_REGEX);
return false;
}
return true;
}
}
You can validate your regular expression with a regular expression and up to a certain limit. Checkout this stack overflow answer for more info.
Note: a "recursive regular expression" is not a regular expression, and this extended version of regex doesn't match extended regexes.
A better option is to use preg_match and match against NULL as #Claudrian said
I am not sure if it supports PCRE, but there is a Chrome extension over at https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib called RegExp Tester. I have not used it as yet myself so I cannot vouch for it, but perhaps it could be of use?
I'd be inclined to set up a number of unit tests for your regex. This way not only would you be able to ensure that the regex is indeed valid but also effective at matching.
I find using TDD is an effective way to develop regex and means that extending it in the future is simplified as you already have all of your test cases available.
The answer to this question has a great answer on setting up your unit tests.
So in summary, for all those coming to this question you can validate regular expressions in PHP with a function like this.
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred. - PHP Manual
/**
* Return an error message if the regular expression is invalid
*
* #param string $regex string to validate
* #return string
*/
function invalidRegex($regex)
{
if(preg_match($regex, null) !== false)
{
return '';
}
$errors = array(
PREG_NO_ERROR => 'Code 0 : No errors',
PREG_INTERNAL_ERROR => 'Code 1 : There was an internal PCRE error',
PREG_BACKTRACK_LIMIT_ERROR => 'Code 2 : Backtrack limit was exhausted',
PREG_RECURSION_LIMIT_ERROR => 'Code 3 : Recursion limit was exhausted',
PREG_BAD_UTF8_ERROR => 'Code 4 : The offset didn\'t correspond to the begin of a valid UTF-8 code point',
PREG_BAD_UTF8_OFFSET_ERROR => 'Code 5 : Malformed UTF-8 data',
);
return $errors[preg_last_error()];
}
Which can be used like this.
if($error = invalidRegex('/foo//'))
{
die($error);
}
You could use valid() from T-Regx
pattern('InvalidRegular)Expression')->valid(); // bool (false)
just use the easy way - look if the preg_match is return a false value:
//look is a regex or not
$look = "your_regex_string";
if (preg_match("/".$look."/", "test_string") !== false) {
//regex_valid
} else {
//regex_invalid
}
You should try to match the regular expression against NULL. If the result is FALSE (=== FALSE), there was an error.
In PHP >= 5.5, you can use the following to automatically get the built-in error message, without needing to define your own function to get it:
// For PHP >= 8, use the built-in strEndsWith instead of this function.
// Taken from https://www.php.net/manual/en/function.str-ends-with.php#125967
function endsWith($haystack, $needle) {
$length = strlen($needle);
return $length > 0 ? substr($haystack, -$length) === $needle : true;
}
function test_regex($regex) {
preg_match($regex, NULL);
$constants = get_defined_constants(true)['pcre'];
foreach ($constants as $key => $value) {
if (!endsWith($key, '_ERROR')) {
unset($constants[$key]);
}
}
return array_flip($constants)[preg_last_error()];
}
Try it online!
Note that the call to preg_match() will still throw a warning for invalid regular expressions. The warning can be caught with a custom error handler using set_error_handler().
See Can I try/catch a warning?.
According to the PCRE reference, there is no such way to test validity of an expression, before it's used. But i think, if someone use an invalid expression, it's a design error in that application, not a run-time one, so you should be fine.

Categories