Reputation: 21
I want to solve the following problem through regular expression
If 1 holds (but 2 does not), return 1.
If both 1 and 2 hold, return 2.
Otherwise return 0.
here is my code.
function checkstrling($input, $substring)
{
$voodoo = preg_match("(".implode("(.*?)",array_map('preg_quote',str_split($substring))).")",$input,$matches);
if( !$voodoo) return 0; // no match
$pieces = implode("",array_slice($matches,1)); // in-between bits
if( $pieces !=="") return 1; // there was stuff in between
return 2; // substring found without interruption
}
var_dump(checkstrling("xgolensssx","golden"));
var_dump(checkstrling("abcgxyommlgdqqesn","golden"));
var_dump(checkstrling("xgoldensssx","golden"));
The function work find when i call and provide the following parameter it work fine.
var_dump(checkstrling("xgolensssx","golden"));
var_dump(checkstrling("abcgxyommlgdqqesn","golden"));
var_dump(checkstrling("xgoldensssx","golden"));
But does not work properly when i call the function again with the following paramenter.
var_dump(checkstrling("somegxoxdxlxnmme","golden"));
var_dump(checkstrling("somegxoxlxdxemnmgoldenv","golden"));
Upvotes: 2
Views: 61
Reputation: 22837
No need for regex here, it'll just complicate things.
function checkstrling($input, $substring)
{
if (strpos($input, $substring) !== false) {
return 2;
}
foreach (str_split($substring) as $char) {
if (strpos($input, $char) === false) {
return 0;
}
}
return 1;
}
print checkstrling("xgolensssx","golden"); // 0
print checkstrling("abcgxyommlgdqqesn","golden"); // 1
print checkstrling("xgoldensssx","golden"); // 2
print checkstrling("somegxoxdxlxnmme","golden"); // 1
print checkstrling("somegxoxlxdxemnmgoldenv","golden"); // 2
Sidenote: You can change str_split($substring)
to array_unique(str_split($substring))
to remove duplicates before going through the loop. This may improve performance for larger $substring
s that contain duplicate letters (such as the word goldenrod
: goldenr
would be the resulting array).
2
, otherwise, continue$substring
0
1
Upvotes: 3
Reputation: 43199
You could use multiple lookaheads:
(?=[^g]*g)
(?=[^o]*o)
(?=[^l]*l)
(?=[^d]*d)
(?=[^e]*e)
(?=[^n]*n)
The pattern is always the same: look for anything not g
zero or more times, than look for g
.
PHP
:
<?php
function checkstrling($input, $substring) {
$regex = '~(?=[^g]*g)(?=[^o]*o)(?=[^l]*l)(?=[^d]*d)(?=[^e]*e)(?=[^n]*n).+~';
if ((preg_match($regex, $input) && (strpos($input, $substring) !== false))) {
return 2;
} else if (preg_match($regex, $input)) {
return 1;
}
return 0;
}
var_dump(checkstrling("xgolensssx","golden"));
var_dump(checkstrling("abcgxyommlgdqqesn","golden"));
var_dump(checkstrling("xgoldensssx","golden"));
var_dump(checkstrling("somegxoxdxlxnmme","golden"));
var_dump(checkstrling("somegxoxlxdxemnmgoldenv","golden"));
?>
Which yields
int(0)
int(1)
int(2)
int(1)
int(2)
Upvotes: 0