Operation on string in PHP. Remove part of string - php

How can i remove part of string from example:
##lang_eng_begin##test##lang_eng_end##
##lang_fr_begin##school##lang_fr_end##
##lang_esp_begin##test33##lang_esp_end##
I always want to pull middle of string: test, school, test33. from this string.
I Read about ltrim, substr and other but I had no good ideas how to do this. Becouse each of strings can have other length for example :
'eng', 'fr'
I just want have string from middle between ## and ##. to Maye someone can help me? I tried:
foreach ($article as $art) {
$title = $art->titl = str_replace("##lang_eng_begin##", "", $art->title);
$art->cleanTitle = str_replace("##lang_eng_end##", "", $title);
}
But there
##lang_eng_end##
can be changed to
##lang_ger_end##
in next row so i ahvent idea how to fix that

If your strings are always in this format, an explode way looks easy:
$str = "##lang_eng_begin##test##lang_eng_end## ";
$res = explode("##", $str)[2];
echo $res;
You may use a regex and extract the value in between the non-starting ## and next ##:
$re = "/(?!^)##(.*?)##/";
$str = "##lang_eng_begin##test##lang_eng_end## ";
preg_match($re, $str, $match);
print_r($match[1]);
See the PHP demo. Here, the regex matches a ## that is not at the string start ((?!^)##), then captures into Group 1 any 0+ chars other than newline as few as possible ((.*?)) up to the first ## substring.
Or, replace all ##...## substrings with `preg_replace:
$re = "/##.*?##/";
$str = "##lang_eng_begin##test##lang_eng_end## ";
echo preg_replace($re, "", $str);
See another demo. Here, we just remove all non-overlapping substrings beginning with ##, then having any 0+ chars other than a newline up to the first ##.

Related

PHP explode string at first alphanumeric character

I have a strings like this.
$str = "-=!#?Bob-Green_Smith";
$str = "-_#!?1241482";
How can I explode them at the first alphanumeric match.
eg:
$str = "-=!#?Bob-Green_Smith";
becomes:
$val[0] = "-=!#?";
$val[1] = "Bob-Green_Smith";
Quick thought some times the string won't contain the initial string of characters,
so I'd need to check if the first character is alphanumeric or not.. otherwise Bob-Green_Smith would get split when he shouldn't.
Thanks
You can use preg_match.
This will match "non word characters" zero or more as first group.
Then the rest as the second.
The output will have three items, the first is the full string, so I use array_shift to remove it.
$str = "-=!#?Bob-Green_Smith";
Preg_match("/(\W*)(.*)/", $str, $val);
Array_shift($val); // remove first item
Var_dump($val);
https://3v4l.org/m2MCg
You can do this like :
$str = "-=!#?1Bob-Green_Smith";
preg_match('~[a-z0-9]~i', $str, $match, PREG_OFFSET_CAPTURE);
echo $bubString = substr($str, $match[0][1]);

Php make spaces in a word with a dash

I have the following string:
$thetextstring = "jjfnj 948"
At the end I want to have:
echo $thetextstring; // should print jjf-nj948
So basically what am trying to do is to join the separated string then separate the first 3 letters with a -.
So far I have
$string = trim(preg_replace('/s+/', ' ', $thetextstring));
$result = explode(" ", $thetextstring);
$newstring = implode('', $result);
print_r($newstring);
I have been able to join the words, but how do I add the separator after the first 3 letters?
Use a regex with preg_replace function, this would be a one-liner:
^.{3}\K([^\s]*) *
Breakdown:
^ # Assert start of string
.{3} # Match 3 characters
\K # Reset match
([^\s]*) * # Capture everything up to space character(s) then try to match them
PHP code:
echo preg_replace('~^.{3}\K([^\s]*) *~', '-$1', 'jjfnj 948');
PHP live demo
Without knowing more about how your strings can vary, this is working solution for your task:
Pattern:
~([a-z]{2}) ~ // 2 letters (contained in capture group1) followed by a space
Replace:
-$1
Demo Link
Code: (Demo)
$thetextstring = "jjfnj 948";
echo preg_replace('~([a-z]{2}) ~','-$1',$thetextstring);
Output:
jjf-nj948
Note this pattern can easily be expanded to include characters beyond lowercase letters that precede the space. ~(\S{2}) ~
You can use str_replace to remove the unwanted space:
$newString = str_replace(' ', '', $thetextstring);
$newString:
jjfnj948
And then preg_replace to put in the dash:
$final = preg_replace('/^([a-z]{3})/', '\1-', $newString);
The meaning of this regex instruction is:
from the beginning of the line: ^
capture three a-z characters: ([a-z]{3})
replace this match with itself followed by a dash: \1-
$final:
jjf-nj948
$thetextstring = "jjfnj 948";
// replace all spaces with nothing
$thetextstring = str_replace(" ", "", $thetextstring);
// insert a dash after the third character
$thetextstring = substr_replace($thetextstring, "-", 3, 0);
echo $thetextstring;
This gives the requested jjf-nj948
You proceeding is correct. For the last step, which consists in inserting a - after the third character, you can use the substr_replace function as follows:
$thetextstring = 'jjfnj 948';
$string = trim(preg_replace('/\s+/', ' ', $thetextstring));
$result = explode(' ', $thetextstring);
$newstring = substr_replace(implode('', $result), '-', 3, false);
If you are confident enough that your string will always have the same format (characters followed by a whitespace followed by numbers), you can also reduce your computations and simplify your code as follows:
$thetextstring = 'jjfnj 948';
$newstring = substr_replace(str_replace(' ', '', $thetextstring), '-', 3, false);
Visit this link for a working demo.
Oldschool without regex
$test = "jjfnj 948";
$test = str_replace(" ", "", $test); // strip all spaces from string
echo substr($test, 0, 3)."-".substr($test, 3); // isolate first three chars, add hyphen, and concat all characters after the first three

How to not perform preg_replace if subject starts with quote

I'm trying to convert plain links to HTML links using preg_replace. However it's replacing links that are already converted.
To combat this I'd like it to ignore the replacement if the link starts with a quote.
I think a positive lookahead may be needed but everything I've tried hasn't worked.
$string = 'test http://www.example.com';
$string = preg_replace("/((https?:\/\/[\w]+[^ \,\"\n\r\t<]*))/is", "$1", $string);
var_dump($string);
The above outputs:
http://www.example.com">test</a> http://www.example.com
When it should output:
test http://www.example.com
You might get along with lookarounds.
Lookarounds are zero-width assertions that make sure to match/not to match anything immediately around the string in question. They do not consume any characters.
That being said, a negative lookbehind might be what you need in your situation:
(?<![">])\bhttps?://\S+\b
In PHP this would be:
<?php
$string = 'I want to be transformed to a proper link: http://www.google.com ';
$string .= 'But please leave me alone ';
$string .= '(https://www.google.com).';
$regex = '~ # delimiter
(?<![">]) # a neg. lookbehind
https?://\S+ # http:// or https:// followed by not a whitespace
\b # a word boundary
~x'; # verbose to enable this explanation.
$string = preg_replace($regex, "<a href='$0'>$0</a>", $string);
echo $string;
?>
See a demo on ideone.com. However, maybe a parser is more appropriate.
Since you can use Arrays in preg_replace, this might be convenient to use depending on what you want to achieve:
<?php
$string = 'test http://www.example.com';
$rx = array("&(<a.+https?:\/\/[\w]+[^ \,\"\n\r\t<]*>)(.*)(<\/a\>)&si", "&(\s){1,}(https?:\/\/[\w]+[^ \,\"\n\r\t<]*)&");
$rp = array("$1$2$3", "$2");
$string = preg_replace($rx,$rp, $string);
var_dump($string);
// DUMPS:
// 'testhttp://www.example.com'
The Idea
You can split your string at the already existing anchors, and only parse the pieces in between.
The Code
$input = 'test http://www.example.com';
// Split the string at existing anchors
// PREG_SPLIT_DELIM_CAPTURE flag includes the delimiters in the results set
$parts = preg_split('/(<a.*?>.*?<\/a>)/is', $input, PREG_SPLIT_DELIM_CAPTURE);
// Use array_map to parse each piece, and then join all pieces together
$output = join(array_map(function ($key, $part) {
// Because we return the delimiter in the results set,
// every $part with an uneven key is an anchor.
return $key % 2
? preg_replace("/((https?:\/\/[\w]+[^ \,\"\n\r\t<]*))/is", "$1", $part)
: $part;
}, array_keys($parts), $parts);

Splitting a string using lookback in PHP

I have a product feed where the product options is formatted like this:
Color{1} : Black[14], White[42] Size{2} : Small[16], Medium[17], Large[18]
For my script to understand and parse the product options correctly, it needs to be in the following format:
Color:Black,White|Size:Small,Medium,Large
I started out like this to remove unnecessary information:
$matches[1] = preg_replace("/\{\d{1,}\} : /", ': ', $matches[1]);
$matches[1] = preg_replace("/\[\d{1,}\]/", '', $matches[1]);
Which gives this output:
Color: Black, White Size: Small, Medium, Large
But my problem now is "how to insert a pipe before the option name, unless its only one option, or the first option". I guess I need to use some sort of lookback, but I have no idea.
First, split the string into several individual options using preg_split():
$arr = preg_split('/\s+(?=[a-z]+{\d+})/i', $str);
(?=[a-z]+{\d+}) is a positive lookahead that asserts that the whitespace (\s+) is followed by a string of the format <string>{xx}. It's used here to pinpoint on which spaces the split should happen. It's important to note that the lookahead assertion is zero-width, i.e. it doesn't consume any characters at all.
Once you have the split array, loop through it, and remove {xx}, [xx] parts and whitespace:
foreach ($arr as &$str)
$str = preg_replace('/(?:{\d+}|\[\d+\]|\s*)/', '', $str);
Join the array by |:
echo join('|', $arr);
Output:
Color:Black,White|Size:Small,Medium,Large
Demo
This method uses only two iterations of regex substitution
First, delete all spaces along with digits
$re = "/(.\\d+.|[ ]+)/";
$str = "Color{1} : Black[14], White[42] Size{2} : Small[16], Medium[17], Large[18]";
$subst = '';
$result = preg_replace($re, $subst, $str);
Then add in the pipe
$re = "/([a-z])([A-Z])/";
$subst = '\1|\2';
$endresult = preg_replace($re, $subst, $result);
Input:
Color{1} : Black[14], White[42] Size{2} : Small[16], Medium[17], Large[18]
Output:
Color:Black,White|Size:Small,Medium,Large
Here's a quick demo
Note: I'm assuming that the digits are always surrounded by a curly brace or a bracket without any spacing in between and that the quantity names are only alpha character (never digits).

Remove string after a certain character?

How can I remove the remaining part of a string after certain characters like ?, #, &, %, = in PHP? Any ideas? I tried preg_replace(), but I couldn't figure it out.
Update, just realized I read it wrong. You're looking for stuff before, not after. Updated code:
$test_string = 'remember?forget';
preg_match('/([^?#&%=]+)/', $test_string, $matches);
$part_before_char = $matches[1];
After run, $part_before_char = 'remember'
This should work:
$str = "Hello World#somesuffixstr";
preg_match("/^(.*?[?#&%=]).*/", $str, $str);
echo $str[1];
// Should output "Hello World#"
About the regex pattern:
It searches for beginning of string (^), then for any character 0 or more times (which is group #1), then such a symbol like & or %, then any character zero or more times. It replaces the string with the characters matched in group #1.
$str = 'mystring#deletedpartofstring';
$str = preg_replace('/[?#&%=].+/', '', $str);

Categories