how to replace everything after specific word in php - php

$url =file("list.txt");
foreach ($url as $sites) {
$sites = trim($sites);
echo $sites . " </ br>";
}
and list.txt contain some urls
http://example.com/cms/wp-content/themes/
http://example.com/wp-content/plugins/
http://example.com/wp-content/themes/Avada-Child-Theme/
how could i remove the word "/wp-content/" and everything after it
to be
http://example.com/cms
http://example.com
http://example.com

Take a look at the the parameter $before_needle at http://docs.php.net/strstr
$o = strstr($url, '/wp-content/', true);

How about using preg_replace?
Something like that:
$sites = trim(preg_replace( '#/wp-content.*#', '', $sites));

This should work:
<?php
$url =file("list.txt");
foreach ($url as $sites) {
$sites = trim($sites);
$pos = strpos($sites, 'wp-content');
$newStr = substr($sites,0,$pos );
echo $newStr . " </ br>";
}
?>

$lines = file('list.txt');
$find = '/wp-content/';
foreach ($lines as $line) {
$line = trim($line);
$pos = strpos($line, $find);
if($pos !== false) {
echo substr($line, 0, $pos) . '<br>';
} else {
echo 'Not found ' . $find . '<br>';
}
}

First explode your content by new line then loop through each and use substr function to remove the matches. Following function my be useful to you:
<?php
// can remove variables from: full url, from urls related to site root, form just a query string like "a=1&b=2"
if(!function_exists("remove_var_from_url")){
function remove_var_from_url($variable_name, $url_string){
// this is anything before the "?" sign
$base_url = '';
// the variable separator, can be "?" if is a full URL or can be empty, if we just have "&sort=sales&oprder=asc"
$separator = "";
$start_pos = 0;
$return_string = "";
//
if(strpos($url_string,"?")!==false){
$start_pos = strpos($url_string, "?")+1;
$separator = "?";
$base_url = substr($url_string, 0, $start_pos-1);
}
// start building the string from the base url (which can be empty)
$return_string = $base_url;
$url_vars_string = substr($url_string, $start_pos);
$names_and_values = explode("&", $url_vars_string);
//
foreach($names_and_values as $value){
list($var_name, $var_value) = explode("=", $value);
if($var_name != $variable_name){
// add the "?" once if needed
if(!$separator_added){
$return_string.= $separator;
$separator_added = true;
} else {
$return_string.= "&";
}
$return_string.= $var_name."=".$var_value;
}
}
// remove "&" from margins
$return_string = trim($return_string, "&");
// remove the "?" if is at the end, it means it was just one variable that was removed
$return_string = rtrim($return_string, "?");
return $return_string;
}
}
?>

I would rather suggest you to apply strpos on each of the string first. Strpos will return you the position of first occurance of a string. Then use substr to fetch everything prior to that string.
` $lines = file('list.txt');
$find = '/wp-content/';
foreach ($lines as $line) {
$position = strpos($line, '/wp-content');
if($position)
$string = substr($line, 0, $position);
}`

Related

Link all tags within content variable

I want to link all tags inside content variable, I can achieve it with foreach, but if one tag is car wash and another is car it's creating link inside link, how to avoid that ?
My code:
$tags = Tag::all();
foreach ($tags as $tag) {
if(stripos($content, $tag->name) !== false) {
$content = str_ireplace($tag->name, '' . $tag->name . '', $content);
}
}
One of the solutions would be sorting tags by length, from small to larg, but nah, I need a better solution
EDIT: Storing already matched tags in a new array and checking with foreach and strpos if they contain substring before replacing, will be a solution for that, but another issue, strpost ans str_replace will match partial words like, if tag is car and content contains caring, there will be a partial match and it will also get replaced, how to avoid partial match ?
EDIT 2: Thanks #Kinglish for help, final code:
$tags = Tag::orderByRaw('CHAR_LENGTH(name) DESC')->get();
$linkedTags = [];
foreach ($tags as $tag) {
foreach ($linkedTags as $linkedTag) {
if(stripos($linkedTag, $tag->name) !== false) {
continue 2;
}
}
if(stripos($content, $tag->name) !== false) {
$pos = stripos($content, $tag->name);
$disallowedCharacters = [
'-',
'/',
'#',
'\\',
'#',
'*',
'&'
];
if ($pos != 0) {
$charBefore = substr($content, $pos -1, 1);
if (ctype_alpha($charBefore) || ctype_digit($charBefore) || in_array($charBefore, $disallowedCharacters)) {
continue;
}
}
$charAfter = substr($content, $pos + strlen($tag->name), 1);
if (ctype_alpha($charAfter) || ctype_digit($charAfter) || in_array($charAfter, $disallowedCharacters)) {
continue;
}
$linkedTags[] = $tag->name;
$content = str_ireplace($tag->name, '' . $tag->name . '', $content);
}
}
Well here's an idea that might work for you...
Store the found tags in an array and remove from content so they don't get picked up twice. Then reassemble the content at the end...
// sort array from longest to shortest
function sort($a,$b){
return strlen($b)-strlen($a);
}
usort($tags,'sort');
$found=array();
foreach ($tags as $tag) {
if(stripos($content, $tag->name) !== false) {
// test the string for partial match
$pos = stripos($content, $tag->name);
// test the character before
if ($pos != 0) {
$charBefore = substr($content, $pos -1, 1);
if (ctype_alpha($charBefore)) {
// its a partial, the character before the string is a letter
continue;
}
}
// test the character after
$charAfter = substr($content, $pos + strlen($tag->name), 1);
if (ctype_alpha($charAfter)) {
// its a partial, the character after the string is a letter
continue;
}
$storedlink = '' . $tag->name . '';
$found[] = $storedlink;
// get ref
$ref = '[!'.count($found).'!]';
$content = str_ireplace($tag->name, $ref, $content);
}
// reassemble
$ctr=0;
foreach ($found as $tag) {
$content = str_replace('[!'.$ctr.'!]', $tag, $content) ;
$ctr++;
}
}
Here is my solution to make link tags, avoiding partial match:
$tags = Tag::all();
$space_order_tags = [];
foreach ($tags as $tag) {
$space_order_tags[count(explode(' ', $tag->name))][] = $tag;
}
$replaced = [];
foreach (array_reverse($space_order_tags) as $tag_array) {
foreach ($tag_array as $tag) {
$replaced[$tag->name] = [$tag->id, hash('md5', $tag->name)];
$content = preg_replace( "/\b$tag->name\b/", $replaced[$tag->name][1], $content);
}
}
foreach (array_keys($replaced) as $tag_name) {
$content = str_ireplace($replaced[$tag_name][1], '' . $tag_name . '', $content);
}
var_dump($content);

First word of a comma separated sentence php

My string is : Hi my, name is abc
I would like to output "Hi Name".
[Basically first word of comma separated sentences].
However sometimes my sentence can also be Hi my, "name is, abc"
[If the sentence itself has a comma then the sentence is enclosed with ""].
My output in this case should also be "Hi Name".
So Far I've done this
$str = "hi my,name is abc";
$result = explode(',',$str); //parsing with , as delimiter
foreach ($result as $results) {
$x = explode(' ',$results); // parsing with " " as delimiter
forach($x as $y){}
}
You can use explode to achieve YOUR RESULT and for IGINORE ' OR " use trim
$str = 'hi my,"name is abc"';
$result = explode(',',$str); //parsing with , as delimiter
$first = explode(' ',$result[0]);
$first = $first[0];
$second = explode(' ',$result[1]);
$second = trim($second[0],"'\"");
$op = $first." ".$second;
echo ucwords($op);
EDIT or if you want it for all , separated values use foreach
$str = 'hi my,"name is abc"';
$result = explode(',',$str); //parsing with , as delimiter
$op = "";
foreach($result as $value)
{
$tmp = explode(' ',$value);
$op .= trim($tmp[0],"'\"")." ";
}
$op = rtrim($op);
echo ucwords($op);
Basically it's hard to resolve this issue using explode, str_pos, etc. In this case you should use state machine approach.
<?php
function getFirstWords($str)
{
$state = '';
$parts = [];
$buf = '';
for ($i = 0; $i < strlen($str); $i++) {
$char = $str[$i];
if ($char == '"') {
$state = $state == '' ? '"' : '';
continue;
}
if ($state == '' && $char == ',') {
$_ = explode(' ', trim($buf));
$parts[] = ucfirst(reset($_));
$buf = '';
continue;
}
$buf .= $char;
}
if ($buf != '') {
$_ = explode(' ', trim($buf));
$parts[] = ucfirst(reset($_));
}
return implode(' ', $parts);
}
foreach (['Hi my, "name is, abc"', 'Hi my, name is abc'] as $str) {
echo getFirstWords($str), PHP_EOL;
}
It will output Hi Name twice
Demo

How to use strstr() php

I want to cut text in array but I have no idea to cut this
I try strstr() but it not true.
I try
$ff='';
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){
$ff .= $row['fav'] . ",";
}
if( strpos( $ff, "_" )) {
$text = strstr($ff, '_');
echo $text;
}
$ff ='A_0089,A_5677,B_4387,A_B_5566,'
I want output show
0089,5677,4387,B_5566,
Here is one example, using substr() with strpos():
$ff='A_0089,A_5677,B_4387,A_B_5566';
$items = explode(',', $ff);
foreach($items as $item) {
echo substr($item, strpos($item, '_')) . "\n";
}
The above code returns:
_0089
_5677
_4387
_B_5566
You're better off not building a string, but building an array. The way you build the string you have a dangling comma, which you do not want.
$ff = array();
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){
$ff[] = $row['fav'];
}
foreach($ff as $item) {
echo substr($item, strpos($item, '_')) . "\n";
}
Based on your desire to keep the commas and create a string:
$ff='A_0089,A_5677,B_4387,A_B_5566,';
$items = explode(',', $ff);
foreach($items as $item) {
$new[] = substr($item, strpos($item, '_'));
}
$newFF = implode(',', $new);
echo $newFF;
returns:
_0089,_5677,_4387,_B_5566,
Probably this is what you are looking for
<?php
function test_alter(&$item1)
{
$pattern = '/^[A-Z]{1}[_]{1}/';
$item1 =preg_replace($pattern,"",$item1);
}
$ff="A_0089,A_5677,B_4387,A_B_5566,";
$nff=explode(",",$ff);
array_walk($nff, 'test_alter');
echo implode(",",$nff);
?>

How to trim all leading/trailing <br> code using php

I am trying to remove all leading and trailing <br> in a string using PHP.
Here is an example
<br><br>
Hello<br>
World<br>
<p>This is a message<br>...</p>
<br><br><br><br>
I want to return
Hello<br>
World<br>
<p>This is a message<br>...</p>
I tried to do the following
echo trim($str, '<br>');
But it does not remove them. How can I remove the new line html code?
Use preg_replace with the beginning ^ and end $ anchors:
$string = preg_replace('/^(<br>){0,}|(<br>){0,}$/', '', $string);
Or for multiple lines:
$string = preg_replace('/^(<br>){0,}|(<br>){0,}$/m', '', $string);
You could also trim() it multiple times:
while($string !== ($string = trim($string, '<br>'))){}
This function does the job. Also applicable to anything else really.
//remove all leading and trailing occurences of needle ($n) from haystack ($h)
function trimAll($h, $n){
if(!$h = trim($h,$n)){
trimAll($h, $n);
}
return $h;
}
I wrote this function that will do the job a little better as it gives me more flexibility on what characters to remove and when this function by default will first remove the leading/trailing characters in order:
any tabs
any new lines
any
any
any tabs
any new lines
function trimString($str, $myList = array("\t","\n", "<br>","<br />", "\t","\n") ){
if( ! is_array($myList) ){
$charsToTrim[] = $chr;
} else {
$charsToTrim = $myList;
}
foreach($charsToTrim as $chr){
$len = strlen($chr);
$nlen = $len * -1;
while( substr($str, 0, $len) == $chr){
$str = trim(substr($str, $len));
}
while( substr($str, $nlen) == $chr){
$str = trim(substr($str, 0, $nlen));
}
}
return $str;
}
to use
// default use case
echo trimString($message);
or
//remove only one string
echo trimString($message, '<br>'); // remove only the leading training '<br>'
or
//remove more than 1 string in order
echo trimString($message, array('<br>'<br />') );
I hope this helps someone out there :)
$p=array(
'<br><br>',
'Hello<br>',
'World<br>',
'<p>This is a message<br>...</p>',
'<br><br><br><br>'
);
function trimdeluxe($str, $sub)
{
$parts=explode($sub, $str);
for ($x=0; $x<2; $x++) {
foreach ($parts as $i=>$v) {
if (!strlen($v)) {
unset($parts[$i]);
} else {
break;
}
}
$parts=array_reverse($parts);
}
return implode($sub,$parts);
}
foreach ($p as $str) {
print $str . ' -> ' . trimdeluxe($str, '<br>') . "\n";
}

match the first & last whole word in a variable

I use php preg_match to match the first & last word in a variable with a given first & last specific words,
example:
$first_word = 't'; // I want to force 'this'
$last_word = 'ne'; // I want to force 'done'
$str = 'this function can be done';
if(preg_match('/^' . $first_word . '(.*)' . $last_word .'$/' , $str))
{
echo 'true';
}
But the problem is i want to force match the whole word at (starting & ending) not the first or last characters.
Using \b as boudary word limit in search:
$first_word = 't'; // I want to force 'this'
$last_word = 'ne'; // I want to force 'done'
$str = 'this function can be done';
if(preg_match('/^' . $first_word . '\b(.*)\b' . $last_word .'$/' , $str))
{
echo 'true';
}
I would go about this in a slightly different way:
$firstword = 't';
$lastword = 'ne';
$string = 'this function can be done';
$words = explode(' ', $string);
if (preg_match("/^{$firstword}/i", reset($words)) && preg_match("/{$lastword}$/i", end($words)))
{
echo 'true';
}
==========================================
Here's another way to achieve the same thing
$firstword = 'this';
$lastword = 'done';
$string = 'this can be done';
$words = explode(' ', $string);
if (reset($words) === $firstword && end($words) === $lastword)
{
echo 'true';
}
This is always going to echo true, because we know the firstword and lastword are correct, try changing them to something else and it will not echo true.
I wrote a function to get Start of sentence but it is not any regex in it.
You can write for end like this. I don't add function for the end because of its long...
<?php
function StartSearch($start, $sentence)
{
$data = explode(" ", $sentence);
$flag = false;
$ret = array();
foreach ($data as $val)
{
for($i = 0, $j = 0;$i < strlen($val), $j < strlen($start);$i++)
{
if ($i == 0 && $val{$i} != $start{$j})
break;
if ($flag && $val{$i} != $start{$j})
break;
if ($val{$i} == $start{$j})
{
$flag = true;
$j++;
}
}
if ($j == strlen($start))
{
$ret[] = $val;
}
}
return $ret;
}
print_r(StartSearch("th", $str));
?>

Categories