I am trying to create a way of making sure that every space has at least three characters (a-zA-Z and single quotes are allowed) on each side of it. It does exactly that, however only with the first space. Not the rest of them. I tried preg_match_all() to no avail, hence my question/post to you guys.
<?PHP
function validateSpaces($str) {
if ( strpos( $str, ' ' ) !== FALSE && !preg_match( '/(([a-z\']{3,})([ ]{1})([a-z\']{3,}))/i', $str ) )
return FALSE;
return TRUE;
}
echo validateSpaces( 'Hey There' ); // Valid (correct)
echo validateSpaces( 'He There' ); // Invalid (correct)
echo validateSpaces( 'Hey Ther e' ); // Valid (incorrect)
?>
As you can see, the first two examples are working like they should, but the second one validates although the second space only has one character on the right side of it. Which is not what I want.
Any help or attempt to help is greatly appreciated!
Thank you in advance,
Chris.
Last modification, will macth only if we have ony one space (trim string before trying to match it):
^([a-z']{3,} ?)+$
You could explode the string on spaces and check the array's contents.
Not complete solution:
$temb=explode(' ', $str);
$valid=true;
foreach ($temb as $tt) {
if (strlen($tt)<3 || !{a preg_match for the right characters in $tt}) {
$valid=false;
break;
}
}
Use preg_match_all() rather than preg_match(), and compare the number of results with a substr_count($str,' ') to see that every space matches your regexp criteria
How about this - you could combine the patterns into one if performance is an issue; I find more than one level of conditional logic difficult to read:
function validate( $value )
{
$ptn_a = '/(^| )[A-Za-z\']{0,2} /';
$ptn_b = '/ [A-Za-z\']{0,2}($| )/';
if ( preg_match( $ptn_a, $value ) )
return false;
if ( preg_match( $ptn_b, $value ) )
return false;
return true;
}
var_dump( validate('Hey There') );
var_dump( validate('He There') );
var_dump( validate('Hey Ther e') );
function validate($string = '')
{
$regexp = '/([^\w]|^)([\w]{1,2})([^\w]|$)/';
if (strlen(trim($string)) && !preg_match($regexp, $string)) {
return 'TRUE';
}
return 'FALSE';
}
print validate(' ');
print "\n";
print validate('Hey There');
print "\n";
print validate('He There');
print "\n";
print validate('Hey ');
print "\n";
print validate('Hey Ther e');
print "\n";
print validate('Hey Th ere');
This can also help.
Related
This should be simple. I want to change all of these substrings:
\\somedrive\some\path
into
file://\\somedrive\some\path
but if substrings already have a file:// then I don't want to append it again.
This doesn't seem to do anything:
var_export( str_replace( '\\\\', 'file://\\\\', '\\somedrive\some\path file://\\somedrive\some\path' ) );
What am I doing wrong? Also, the above doesn't take into test for file:// already being there; what's the best way of dealing with this?
UPDATE test input:
$test = '
file://\\someserver\some\path
\\someotherserver\path
';
test output:
file://\\someserver\some\path
file://\\someotherserver\path
Thanks.
You should consider escape sequence in string also.
if((strpos($YOUR_STR, '\\\\') !== false) && (strpos($YOUR_STR, 'file://\\\\') === false))
var_export( str_replace( '\\\\', 'file://\\\\', $YOUR_STR ) );
Use a regular expression to check if the given substring starts with file://. If it does, don't do anything. If it doesn't, append file:// at the beginning of the string:
if (!preg_match("~^file://~i", $str)) {
$str = 'file://' . $str;
}
As a function:
function convertPath($path) {
if (!preg_match("~^file://~i", $path)) {
return 'file://'.$path;
}
return $path;
}
Test cases:
echo convertPath('\\somedrive\some\path');
echo convertPath('file://\\somedrive\some\path');
Output:
file://\somedrive\some\path
file://\somedrive\some\path
EDIT
For multiple occurrences : preg_replace('#((?!file://))\\\\#', '$1file://\\\\', $path)
This will work to give you the output you are expecting. As php.net says double slash will be converted into single slash.
if (!preg_match('/^file:\/\//', $str)) {
$str = "file://\\".stripslashes(addslashes($str));
}
Please try this:
$string = "\\somedrive\some\path";
$string = "\\".$string;
echo str_replace( '\\\\', 'file://\\\\',$string);
I have two strings "Mures" and "Maramures". How can I build a search function that when someone searches for Mures it will return him only the posts that contain the "Mures" word and not the one that contain the "Maramures" word. I tried strstr until now but it does now work.
You can do this with regex, and surrounding the word with \b word boundary
preg_match("~\bMures\b~",$string)
example:
$string = 'Maramures';
if ( preg_match("~\bMures\b~",$string) )
echo "matched";
else
echo "no match";
Use preg_match function
if (preg_match("/\bMures\b/i", $string)) {
echo "OK.";
} else {
echo "KO.";
}
How do you check the result of strstr? Try this here:
$string = 'Maramures';
$search = 'Mures';
$contains = strstr(strtolower($string), strtolower($search)) !== false;
Maybe it's a dumb solution and there's a better one. But you can add spaces to the source and destination strings at the start and finish of the strings and then search for " Mures ". Easy to implement and no need to use any other functions :)
You can do various things:
search for ' Mures ' (spaces around)
search case sensitive (so 'mures' will be found in 'Maramures' but 'Mures' won't)
use a regular expression to search in the string ( 'word boundary + Mures + word boundary') -- have a look at this too: Php find string with regex
function containsString($needle, $tag_array){
foreach($tag_array as $tag){
if(strpos($tag,$needle) !== False){
echo $tag . " contains the string " . $needle . "<br />";
} else {
echo $tag . " does not contain the string " . $needle;
}
}
}
$tag_array = ['Mures','Maramures'];
$needle = 'Mures';
containsString($needle, $tag_array);
A function like this would work... Might not be as sexy as preg_match though.
The very simple way should be similar to this.
$stirng = 'Mures';
if (preg_match("/$string/", $text)) {
// Matched
} else {
// Not matched
}
I'm trying to modify this regex pattern so that it disallows two specified characters in a row or at the start/end -
/^[^\!\"\£\$\%\^\&\*\(\)\[\]\{\}\#\~\#\/\>\<\\\*]+$/
So at the moment it prevents these characters anywhere in the string, but I also want to stop the following from happening with these characters:
any spaces, apostophes ', underscores _ or hyphens - or dots . appearing at the start of end of the string
also prevent any two of these characters in a row, i.e. '' or _._ or ' -__- ' .
Any help would be hugely appreciated.
Thanks a lot
One way
/^(?=[^!"£$%^&*()[\]{}#~#\/><\\*]+$)(?!.*[ '_.-]{2})[^ '_.-].*[^ '_.-]$/
Note, only tested as javascript regex, i.e.
var rex = /^(?=[^!"£$%^&*()[\]{}#~#\/><\\*]+$)(?!.*[ '_.-]{2})[^ '_.-].*[^ '_.-]$/;
rex.test('okay'); // true
rex.test('_not okay'); // false
Or, to match on disallowed patterns
/^[ '_.-]|[ '_.-]$|[!"£$%^&*()[\]{}#~#\/><\\*]|[ '_.-]{2}/
The first regex will only match strings that contain no disallowed patterns.
The one above will match any disallowed patterns in a string.
Update
Now tested briefly using php. The only difference is that the " in the character set needed to be escaped.
<?php
$test = 'some string';
$regex = "/^[ '_.-]|[ '_.-]$|[!\"£$%^&*()[\]{}#~#\/><\\*]|[ '_.-]{2}/";
if ( preg_match( $regex, $test ) ) {
echo 'Disallowed!';
}
$tests[1] = "fail_.fail"; // doubles
$tests[] = "fail_-fail";
$tests[] = "fail_ fail";
$tests[] = "fail fail";
$tests[] = "fail -fail";
$tests[] = "pas.s_1";
$tests[] = "pa.s-s_2"; // singles
$tests[] = "pas.s_3";
$tests[] = "p.a.s.s_4";
$tests[10] = "pa s-s_5";
$tests[] = "fail fail'"; // pre or post-pended
$tests[] = " fail fail";
$tests[] = " fail fail";
$tests[] = "fail fail_";
$tests[15] = "fail fail-";
// The list of disallowed characters. There is no need to escape.
// This will be done with the function preg_quote.
$exclude = array(" ","'", "_", ".", "-");
$pattern = "#[" . preg_quote(join("", $exclude)) . "]{2,}#s";
// run through the simple test cases
foreach($tests as $k=>$test){
if(
in_array(substr($test, 0, 1), $exclude)
|| in_array(substr(strrev($test), 0 , 1) , $exclude))
{
echo "$k thats a fail" . PHP_EOL;
continue;
}
$test = preg_match( $pattern, $test);
if($test === 1){
echo "$k - thats a fail". PHP_EOL ;
}else{
echo "$k - thats a pass $test ". PHP_EOL ;
}
}
Stealing hopelessly from other replies, I'd advocate using PHPs simple in_array to check the start and end of the string first and just fail early on discovering something bad.
If the test gets past that, then run a really simple regex.
Stick the lot into a function and return false on failure -- that would rm quite a few verbose lines I added -- you could even send in the exclusion array as a variable -- but it would seem rather a specific function so may be YAGNI
eg
if( badString($exclude_array, $input) ) // do stuff
I'm not sure I understand the exact problem, but here's a suggestion:
<?php
$test = "__-Remove '' _._ or -__- but not foo bar '. _ \n";
$expected = 'Remove or but not foo bar';
// The list of disallowed characters. There is no need to escape.
// This will be done with the function preg_quote.
$excluded_of_bounds = "'_.-";
// Remove disallowed characters from start/end of the string.
// We add the space characters that should not be in the regexp.
$test = trim($test, $excluded_of_bounds . " \r\n");
// In two passes
$patterns = array(
// 1/ We remove all successive disallowed characters,
// excepted for the spaces
'#[' . preg_quote($excluded_of_bounds) . ']{2,}#',
// 2/ We replace the successive spaces by a unique space.
'#\s{2,}#',
);
$remplacements = array('', ' ');
// Go!
$test = preg_replace($patterns, $remplacements, $test);
// bool(true)
var_dump($expected === $test);
i am using following code to return only digital values from the variable, wounder how to get only character value "testing" from the variable and want to remove "on" from the string.
<?php
$valuecheck="testing on 123568";
$check1=preg_replace('/\D/', '', $valuecheck);
echo $check1;
?>
Output required:
testing
Thanks
Instead of \D, use [^a-zA-Z] (assuming that's what you mean by "character value"). Basically, put [^SOMETHING], where that "something" is a set of all the characters you want to consider valid.
I'm afraid my solution would be a little more verbose:
$result = '';
$c = explode( ' ', $valuecheck );
foreach ($c as $ci) {
if (preg_match( '[\D]', $ci ) == 1) { continue; }
$result = $ci; break;
}
echo $result;
Treating space as a delimiter, this will ignore any strings with at least one numeric and return the first "qualified" string found.
I want to match an input string to my PHP page the same way a match done by the LIKE command in SQL (MySQL) for consistency of other searches. Since (I have seen but don't comprehend) some of the PHP syntax includes SQL commands I am wondering if this is possible?
The reason for this is I am now implementing a search of a keyword versus fields in the DB that are stored in a serialized array, which I have to unserialize in PHP and search depending on the structure of the array. I can't query against the table, just need the matching ability of the query. Otherwise I need to find an alternate matching routine, which won't be consistent. I can't go back and re-structure the DB since this wasn't anticipated wayyy back in the spec. Yes, I need an ugly hack, but am looking for the most elegant.
If it's not possible I could use any recommendation of matching user typed text as a keyword against stored text.
EDIT (for clarification): my main problem is I don't have a thorough grasp on how the LIKE command works (just copying the code) and as the keyword implies some degree of vagueness, I would like that vagueness preserved if I switch to a regular expression. I am better with regex's just not so good with like. My query is "LIKE 'matchme%'"
Update
Based on tomalak's comment and OIS's brilliant idea to use preg_grep, this might be something more along the lines of a final solution for you.
<?php
function convertLikeToRegex( $command )
{
return "/^" . str_replace( '%', '(.*?)', preg_quote( $command ) ) . "$/s";
}
function selectLikeMatches( $haystack, $needle )
{
return preg_grep( convertLikeToRegex( $needle ), $haystack );
}
$likeClauses = array(
'%foo'
,'foo%'
,'%foo%'
);
$testInput = array(
'foobar'
,'barfoo'
,'barfoobaz'
);
foreach ( $likeClauses as $clause )
{
echo "Testing $clause:";
echo '<pre>';
print_r( selectLikeMatches( $testInput, $clause ) );
echo '</pre>';
}
Original Post Below
Is this along the lines of what you're after?
<?php
function convertLikeToRegex( $command )
{
return "/^" . str_replace( '%', '(.*?)', $command ) . "$/s";
}
$likeClauses = array(
'%foo'
,'foo%'
,'%foo%'
);
$testInput = array(
'foobar'
,'barfoo'
,'barfoobaz'
);
foreach ( $testInput as $test )
{
foreach ( $likeClauses as $clause )
{
echo "Testing '$test' against like('$clause'): ";
if ( preg_match( convertLikeToRegex( $clause ), $test ) )
{
echo 'Matched!';
} else {
echo 'Not Matched!';
}
echo '<br>';
}
echo '<hr>';
}
What you need is preg_grep actually.
$arr = array("tstet", "duh", "str");
$res = preg_grep("#st#i", $arr); //i for case insensitive
var_dump($res);
results in
array(2) {
[0]=>
string(5) "tstet"
[2]=>
string(3) "str"
}
edit:
the user supplies the text, I add the
wildcards behind the scenes. I do use
one %. LIKE 'text%'
here is how you specify it in regex
"#st#i" regex is the same as in sql "%st%"
"#^st#i" regex is the same as in sql "st%"
"#st$#i" regex is the same as in sql "%st"
Also, remember to use preg_quote on any text you get from a third party.
$regex = "#" . preg_quote($text) . "#i";
$res = preg_grep($regex, $arr);
I'd think you'd need preg_match but that's not exactly the same behavior as a LIKE.
<?php // The "i" after the pattern delimiter indicates a case-insensitive search
if (preg_match("/php/i", "PHP is the web scripting language of choice.")) {
echo "A match was found.";
} else {
echo "A match was not found."; }
?>
Do you mean you want to be able to check if the input string is LIKE var% ?
You could use strpos(haystack, needle) to match %var%.
if( strpos($source, "var") == 0 ) echo "matches var%";
if( strlen($source) - (strpos($source, "var")) == strlen("var") ) echo "matches %var";
That is pretty ugly. And actually probably not the most elegant.