How to find positions of a character in a string or sentence in php
$char = 'i';
$string = 'elvis williams';
$result = '3rd ,7th and 10th'.
I tried strpos..but no use..
This will give you the position of $char in $string:
$pos = strpos($string, $char);
If you want the position of all occurences of $char in string:
$positions = array();
$pos = -1;
while (($pos = strpos($string, $char, $pos+1)) !== false) {
$positions[] = $pos;
}
$result = implode(', ', $positions);
print_r($result);
Test it here: http://codepad.viper-7.com/yssEK3
Related
I am writing some unit tests for some methods I am using, and have found a weird bug and would like some Regex advice.
when doing:-
$needle = ' ';
$haystack = 'hello world. this is a unit test.';
$pattern = '/\b' . $needle . '\b/';
preg_match_all($pattern, $haystack, $matches, PREG_OFFSET_CAPTURE, $offset)
I'm expecting the positions to positions found to be
[5, 12, 17, 20, 22, 27]
The same as if I did this, to get none exact whole word matches
while (($pos = strpos($haystack, $needle, $offset)) !== false) {
$offset = $pos + 1;
$positions[] = $pos;
}
However the preg_match_all does not find the 2nd occurrence (12) the space between
. this
Is this to do with the \b boundary flag? How can I resolve this to make sure it picks up other this?
Thanks
You have to change your $pattern in preg_match_all() like below:-
<?php
$haystack = 'hello world. this is a unit test.';
while (($pos = strpos($haystack, ' ', $offset)) !== false) {
$offset = $pos + 1;
$positions[] = $pos;
}
echo "<pre/>";print_r($positions);
preg_match_all('/\s/', $haystack, $matches,PREG_OFFSET_CAPTURE);
echo "<pre/>";print_r($matches);
Output:- https://eval.in/725574
Note:- you need to use \s for checking white-spaces
You can apply an if-else to change $pattern based on $needle:-
if($needle == ''){
$pattern = '/\s/';
}else{
$pattern = '/\b' . $needle . '\b/';
}
I want to get the position of 'ja' in each of the words in $string, but its not working. what am i doing wrong?
<?php
$offset = 0;
$find = 'ja';
$find_length = strlen($find);
$string = 'jasim jasmin jassir';
while ($string_position = strpos($string, $find, $offer)) {
echo $find.' found at '.$string_position.'<br>';
$offset = $string_position + $find_length;
}
?>
Change the variable name to $offset
strpos may return 0 and while will treat it as false
So replace your while statement with:
while (($string_position = strpos($string, $find, $offset)) !== false) {
<?php
// stack overflow area
$offset = 0;
$find = 'ja';
$find_length = strlen($find);
$string = 'jasim jasmin jassir';
if (strpos($string, $find) === false) {
echo "not found";
}
else {
while (strpos($string, $find, $offset) !== false) {
$string_position = strpos($string, $find, $offset);
echo $find.' found at '.$string_position.'<br>';
$offset = $string_position + $find_length;
}
}
?>
Little workaround, but it apparently works.
Output:
ja found at 0
ja found at 6
ja found at 13
try changing offest
<?php
$offset = 1;
$find = 'ja';
$find_length = strlen($find);
$string = 'jasim jasmin jassir';
while ($string_position = strpos($string, $find, $offset)) {
echo $find.' found at '.$string_position.'<br>';
$offset = $string_position + $find_length;
}
?>
// output :- ja found at 6
ja found at 13
if you don't want to change offset use
$string = ' jasim jasmin jassir'; (without space not be jasim it's 'jasim )
then it will output 3
ja found at 1
ja found at 7
ja found at 14
OR try to change your condition check
while (($string_position = strpos($string, $find, $offset)) !== false) {
Probably you should code this way to find string positions
$positions = array();
$offset = -1;
while (($pos = strpos($string, $find, $offset+1)) !== false) {
$positions[] = $offset;
}
$result = implode(', ', $positions);
print this result
$find = '{<p>something</p>}';
$str1 = "<p>{<p>something</p>}</p>\r\ntext<p>something else</p>";
// or
$str2 = "<p>something</p>\r\n{<p>something</p>}aa<p>t</p>\r\ntext<p>something else</p>";
Basically, $find can be anywhere in the string. New lines delimiter is "\r\n".
I need to find $find in the $str and remove specific html tags around $find in that specific string line. No tags should be removed from $find.
Expected output would be
// For $str1
$str1 = "{<p>something</p>}\r\ntext<p>something else</p>";
// For $str2
$str2 = "<p>something</p>\r\n{<p>something</p>}aat\r\ntext<p>something else</p>";
The string might be very long, so no regex solutions please.
What I have figured out:
$pos = strpos($str, $find);
if ($pos !== false) {
$contentLength = strlen($str);
$lineStart = (int)strrpos($str, "\r\n", -$contentLength+$pos); // cast false to 0 (start of string)
$lineEnd = strpos($str, "\r\n", $pos);
if ($lineEnd === false)
$lineEnd = strlen($str);
$lineLength = $lineEnd-$lineStart;
if ($lineLength < 0)
return;
var_dump(substr($str, $lineStart, $lineLength));
}
Which dumps that specific line in the string.
My final solution:
function replace($find, $str, $replace) {
$pos = strpos($str, $find);
if ($pos !== false) {
$delim = "\r\n";
$contentLength = strlen($str);
$lineStart = strrpos($str, $delim, -$contentLength+$pos);
if ($lineStart === false)
$lineStart = 0;
else
$lineStart += strlen($delim);
$lineEnd = strpos($str, $delim, $pos);
if ($lineEnd === false)
$lineEnd = strlen($str);
$lineLength = $lineEnd - $lineStart;
$line = substr($str, $lineStart, $lineLength);
$posLine = strpos($line, $find); // Where $find starts
$findLength = strlen($find);
$line = substr_replace($line, '', $posLine, $findLength); // Remove $find from $line
$begin = replaceTags(substr($line, 0, $posLine));
$end = replaceTags(substr($line, $posLine));
return substr_replace($str, $begin.$replace.$end, $lineStart, $lineLength);
}
}
function replaceTags($str) {
return str_replace(array('<p>', '</p>'), '', $str);
}
echo replace($find, $str, $replace);
I am trying to replace this "iwdnowfreedom[body_style][var]" with this "iwdnowfreedom_body_style_var" in the name attributes of a variable. There could be several array keys but for my situation stripping them out shouldn't result in any issues.
Here is the code I have so far:
$pattern = '/name\\s*=\\s*["\'](.*?)["\']/i';
$replacement = 'name="$2"';
$fixedOutput = preg_replace($pattern, $replacement, $input);
return $fixedOutput;
How can I fix this to work properly?
You could try using the build in str_replace function to achieve what you are looking for (assuming there are no nested bracked like "test[test[key]]"):
$str = "iwdnowfreedom[body_style][var]";
echo trim( str_replace(array("][", "[", "]"), "_", $str), "_" );
or if you prefer regex (nested brackets work fine with this method):
$input = "iwdnowfreedom[body_style][var]";
$pattern = '/(\[+\]+|\]+\[+|\[+|\]+)/i';
$replacement = '_';
$fixedOutput = trim( preg_replace($pattern, $replacement, $input), "_" );
echo $fixedOutput;
I think you also meant that you might have a string such as
<input id="blah" name="test[hello]" />
and to parse the name attribute you could just do:
function parseNameAttribute($str)
{
$pos = strpos($str, 'name="');
if ($pos !== false)
{
$pos += 6; // move 6 characters forward to remove the 'name="' part
$endPos = strpos($str, '"', $pos); // find the next quote after the name="
if ($endPos !== false)
{
$name = substr($str, $pos, $endPos - $pos); // cut between name=" and the following "
return trim(preg_replace('/(\[+\]+|\]+\[+|\[+|\]+)/i', '_', $name), '_');
}
}
return "";
}
OR
function parseNameAttribute($str)
{
if (preg_match('/name="(.+?)"/', $str, $matches))
{
return trim(preg_replace('/(\[+\]+|\]+\[+|\[+|\]+)/i', '_', $matches[1]), '_');
}
return "";
}
I have got a string and would like to remove everything after a certain "dot"+word combination. For instance:
This.Is.A.Test
=> would become
This.Is.A
Were you looking to remove everything after a specific dot+word, or just remove the last dot+word? If you're looking for a specific word, try this:
$str = "This.Is.A.Test";
$find = ".A";
$index = strpos($str, $find);
if ($index !== false)
$str = substr($str, 0, $index + strlen($find));
echo $str; // "This.Is.A"
In response to #SuperSkunk:
If you wanted to match the whole word, you could do this:
$find = ".A.";
$str = "This.Is.A.Test";
$index = strpos($str, $find);
if ($index !== false)
$str = substr($str, 0, $index + strlen($find) - 1);
echo $str; // "This.Is.A"
$str = "This.Is.AB.Test";
$index = strpos($str, $find);
if ($index !== false)
$str = substr($str, 0, $index + strlen($find) - 1);
echo $str; // "This.Is.AB.Test" (did not match)
$str = "This.Is.A.Test"; $str = substr($str, 0, strrpos($str, "."));
$result = explode('.', $str, 4);
array_pop($result);
implode('.', $result);
I'll do something very simple like :
<?php
$string = 'This.Is.A.Test';
$parts = explode('.', $string);
array_pop($parts); // remove last part
$string = implode('.', $parts);
echo $string;
?>
$pos = strpos($haystack, ".A" );
$result = substr($haystack,0,$pos);
...something like this.