How to use php to explode string, remove extra characters - php

I've been using PHP for a while and came across an issue where turning a string into an array (explode), and then simply removing system output characters around each element was not easy to achieve.
I have a string of categories where the output needs to be handled:
2;#Ecosystems;#3;#Core Science Systems (CSS);#4;#Energy and Minerals;#5;#Director
I have tried this particular code below:
$text = "2;#Ecosystems;#3;#Core Science Systems (CSS);#4;#Energy and Minerals;#5;#Director";
$explode = explode('#' , $text);
foreach ($explode as $key => $value)
{
ob_start();
echo ''.$value.'';
$myStr = ob_get_contents();
ob_end_clean();
}
echo "$myStr"
The only element returned is:
Director
Can someone point me in the right direction. I'd like to view the string like this:
Ecosystems; Core Science Systems (CSS); Energy and Minerals; Director

$myStr = ob_get_contents();
This will replace $myStr. What you're probably looking to do is add to it:
$myStr .= ob_get_contents();
Though looking at your required output, your code is not going to achieve what you want, because you're not removing the preceding part e.g. #1;.
Try this
$text = "2;#Ecosystems;#3;#Core Science Systems (CSS);#4;#Energy and Minerals;#5;#Director";
$text = preg_replace('/(#?[0-9];#)/', ' ', $text);
echo $text;
Output: Ecosystems; Core Science Systems (CSS); Energy and Minerals; Director

Your problem is not question-related, you overwrite your buffer with each foreach iteration, the fix is
$myStr .= ob_get_contents();

For this exact example you give you could change the explode to split on ;#
$text = "2;#Ecosystems;#3;#Core Science Systems (CSS);#4;#Energy and Minerals;#5;#Director";
$categories = array();
$explode = explode(';#' , $text);
foreach ($explode as $key => $value)
{
if (!is_numeric($value)) {
$categories[] = $value;
}
}
echo implode("; ", $categories);

The reason is that you place both ob_start() and ob_end_clean() inside the loop. Place them outside the loop:
ob_start();
foreach ($explode as $key => $value)
{
echo ''.$value.'';
$myStr = ob_get_contents();
}
ob_end_clean();
echo "$myStr";

I would use preg_split and do it like this:
$result = implode(' ', preg_split('/#?\d+;#/', $text, null, PREG_SPLIT_NO_EMPTY));

this solves the problem, you can fine-tune the output:
$text = "2;#Ecosystems;#3;#Core Science Systems (CSS);#4;#Energy and Minerals;#5;#Director";
$explode = explode('#' , $text);
$myStr = '';
foreach ($explode as $key => $value)
{
$myStr .= $value;
}
echo "$myStr"

$arr = explode("#", $text);
You can then echo the array in different ways
echo $arr[0] <= the number represents the index of the array value.

Related

Backreference preg_replace with commas in subject

Can you please help me find the preg_replace syntax so i can duplicate the price where it is missing?
The subject is:
...nomaterwhat13124123,"321,00",,nomaterwhat
...nomaterwhat12321,"322,20","134,00",nomaterwhat
...nomaterwhat1321,"211,00",,nomaterwhat
...nomaterwhat31313,"241,00",,nomaterwhat
My output want to be:
...nomaterwhat13124123,"321,00","321,00",nomaterwhat
...nomaterwhat12321,"322,20","134,00",nomaterwhat
...nomaterwhat1321,"211,00","211,00",nomaterwhat
...nomaterwhat31313,"241,00","241,00",nomaterwhat
I tried
preg_replace("(\W+),,nomaterwhat$", "$1,$1,nomaterwhat", $string);
Ignoring more complex cases this should do:
$result = preg_replace('/,"(\d+,\d{2})",,nomaterwhat/', ',"$1",$1,nomaterwhat', $string);
If you use str_getcsv you can do something like this:
$data = "CSV VALUES";
$lines = explode("\n", $data);
foreach ($lines as $line) {
$temp = str_getcsv($line);
echo '<pre>' . print_r($temp, true) . '</pre>';
}
Then you can put these into an array like so:
$data = "CSV VALUES";
$lines = explode("\n", $data);
$output = array();
foreach ($lines as $line) {
$temp = str_getcsv($line);
$temp[5] = ($temp[5] == '') ? $temp[4] : $temp[5];
$output[] = $temp;
}
echo '<pre>' . print_r($output, true) . '</pre>';
Replace $temp[5] with the place that the 2nd price should be.
You have a few issues with your regex.
1. No delimiter
2. No m modifier so $ is the end of the string, not line.
3. \W+ is a non a-z, 0-9, and/or _ so you wouldn't have gotten the
money value there anyway.
Try this out:
$string = '...nomaterwhat13124123,"321,00",,nomaterwhat
...nomaterwhat12321,"322,20","134,00",nomaterwhat
...nomaterwhat1321,"211,00",,nomaterwhat
...nomaterwhat31313,"241,00",,nomaterwhat';
echo preg_replace("/,(\"\d+,\d{2}\"),,nomaterwhat$/m", ",$1,$1,nomaterwhat", $string);
Output:
...nomaterwhat13124123,"321,00","321,00",nomaterwhat
...nomaterwhat12321,"322,20","134,00",nomaterwhat
...nomaterwhat1321,"211,00","211,00",nomaterwhat
...nomaterwhat31313,"241,00","241,00",nomaterwhat
Regex Demo: https://regex101.com/r/hE2zQ7/1
PHP Demo: http://ideone.com/OanPN1

How do I convert a PHP foreach output into a string?

function Foo($word) {
$lowerword= strtolower($word);
$words = explode(" ", $lowerword);
foreach ($words as $wrd){
echo $wrd[0];
}
}
$word = "my name is";
$firstletters = Foo($word);
Source code above. The idea is to take the first letter from each word in a sentence and piece them together as one string that can then be further manipulated. However, I am having difficulty manipulating the output, making me think that the output is not really one string. How do I convert the output of the foreach loop into a string?
The output is not a string at all indeed. Your function does echo but doesn't return anything.
Try this function:
function Foo($word) {
$lowerword= strtolower($word);
$words = explode(" ", $lowerword);
$firstLetters = '';
foreach ($words as $wrd){
$firstLetters .= $wrd[0];
}
return $firstLetters;
}

Extract everything within brackets

I have a string of HTML with tags inside saved in the database e.g:
<p>Hello {$name}, welcome to {$shop_name}....</p>
I want to replace all of the tags with real data, now at the moment I loop through all available data and replace if it exists.
foreach($data as $key => $data){
$content = str_replace('{$'.$key.'}', $data, $content);
}
Is there a better way of doing this without looping through all of the $data? This is now growing to over 5000 rows.
I mean is it possible to extract all variables {$name}/{$shop_name} then do a replace on only the found?
You can do it with a single str_replace call.
$find = array();
$replace = array();
foreach($data as $key => $data) {
$find[] = "\{$" . $key . "}";
$replace[] = $data;
}
$content = str_replace($find, $replace, $content);
Unless there is a real performance issue, I wouldn't worry about it too much.
str_replace accepts arrays, you can build the array with array_keys, array_values and user array_map to add the {$}
$content = str_replace(
array_map(function($e) { return '{$' . $e . '}';}, array_keys($data)),
array_values($data),
$content);
Can just do
$content = preg_replace('/\{$(\w+)\}/e', '$data[\'$1\']', $content);

How to parse PHP code in a PHP array?

I am using this piece of code on a site of mine.
If there is PHP code in the array and if you echo it, it does not run.
There is piece of code;
function spin($var){
$words = explode("{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
echo $word." ";
}
}
}
$text = "example.com is {the best forum|a <? include(\"myfile.php\");?>Forum|a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
The file that needs to be included "myfile.php" will not be included. and the PHP codes will be visible. Why is that? How can I solve this problem?
I believe that you will want to run the include statement through eval(). However note that:
"The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand." (PHP.net)
SOURCE: http://php.net/manual/en/function.eval.php
You might try the following:
<?php
function spin($var)
{
$words = explode("\{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
if ( preg_match( "/\<\? include\(\\\"([A-Za-z\.]+)\\\"\)\;\?\>/", $word ) )
{
$file = preg_replace( "/^.*\<\? include\(\\\"([A-Za-z\.]+)\\\"\)\;\?\>.*\$/", "\$1", $word );
$pre = preg_replace( "/^(.*)\<\? include\(\\\"[A-Za-z\.]+\\\"\)\;\?\>.*\$/", "\$1", $word );
$post = preg_replace( "/^.*\<\? include\(\\\"[A-Za-z\.]+\\\"\)\;\?\>(.*)\$/", "\$1", $word );
echo $pre;
include( $file );
echo $post;
}
}
}
}
$text = "example.com is {the best forum|a <? include(\"myfile.php\");?>Forum|a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
?>
My suggestion is a bit of other way,
function spin($var){
$words = explode("{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
if(str_replace(" ","",$word) == 'thisparam'){
echo 'a';
include("myfile.php");
echo 'Forum';
}else{
echo $word." ";
}
}
}
}
$text = "example.com is {the best forum| thisparam |a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
where thisparam is you variable $test is the parameter to run the if statement.
I place a str_replace infront of $word to replace strings to get exact word.
Well it is just a string of text after all. The echo will just output the text...
I suggest you look to make use of eval http://php.net/manual/en/function.eval.php
I cant really tell why you wish to do this though. Whenever I need to use eval and friends I stop to think "Should I be doing this?"

Replace everything from beginning of line to equal sign

For a content with the format:
KEY=VALUE
like:
LISTEN=I am listening.
I need to do some replacing using regex. I want this regular expression to replace anything before the = with $key (making it have to be from beginning of line so a key like 'EN' wont replace a key like "TOKEN".
Here's what I'm using, but it doesn't seem to work:
$content = preg_replace('~^'.$key.'\s?=[^\n$]+~iu',$newKey,$content);
$content = "foo=one\n"
. "bar=two\n"
. "baz=three\n";
$keys = array(
'foo' => 'newFoo',
'bar' => 'newBar',
'baz' => 'newBaz',
);
foreach ( $keys as $oldKey => $newKey ) {
$oldKey = preg_quote($oldKey, '#');
$content = preg_replace("#^{$oldKey}( ?=)#m", "{$newKey}\\1", $content);
}
echo $content;
Output:
newFoo=one
newBar=two
newBaz=three
$str = 'LISTEN=I am listening.';
$new_key = 'ÉCOUTER';
echo preg_replace('/^[^=]*=/', $new_key . '=', $str);
If I understood your question well, you need to switch the multi-line mode on using m modifier.
$content = preg_replace('/^'.preg_quote($key, '/').'(?=\s?=)/ium', $newKey, $content);
By the way I do recommend to escape the $key using preg_quote to avoid unexpected results.
So if the source content is this:
KEY1=VALUE1
HELLO=WORLD
KEY3=VALUE3
The result will be this (if $key=HELLO and $newKey=BYE):
KEY1=VALUE1
BYE=WORLD
KEY3=VALUE3
This should do the trick.
\A is the start of a line, and the parentheses is for grouping things to keep/replace.
$new_content = preg_replace("/\A(.*)(=.*)/", "$key$2", $content);
$content = 'LISTEN=I am listening.';
$key = 'LISTEN';
$newKey = 'NEW';
$content = preg_replace('~^'.$key.'(\s?=)~iu',$newKey.'$1',$content);
echo $content;
output is NEW=I am listening.
But is does not change on a partial match
$content = 'LISTEN=I am listening.';
$key = 'TEN';
$new_key = 'NEW';
$content = preg_replace('~^'.$key.'(\s?=)~iu',$newKey.'$1',$content);
echo $content;
Output is LISTEN=I am listening.

Categories