preg_replace is modifying JavaScript - php

I have a template tool, that replaces placeholders one of the pieces of the tool loads other files, here is what I am using for debugging:
var_dump($string);
$tmp = preg_replace('/\\$import\(("|\')' . $f . '("|\')\).*;/i', $string, $tmp);
var_dump($tmp);
The first var_dump prints out the contents of a file, and in the file there is this line of JavaScript:
$("#image-menu .info").html(text.replace(/(.+?:)/, "<b>$1</b>"));
After the pre_replace I have the second var_dump which then prints out this:
$("#image-menu .info").html(text.replace(/(.+?:)/, "<b>"</b>"));
As you can see $1 was replaced by a ", and I am not sure why. Any ideas as to why it is getting replaced?
Here is the full method:
private function loadIncludes(){
$tmp = $this->template;
$matches = array();
preg_match_all('/(\\$import\(("|\')(.+?)("|\')\).*;)/i', $tmp, $matches);
$files = $matches[3];
$replace = 0;
foreach($files as $key => $file){
$command = preg_replace("/\\\$import\((\"|').+?(\"|')\)/", "", $matches[0][$key]);
$string = $this->import($file);
$string = $this->runFunctions($string, "blah" . $command);
$f = preg_quote($file, "/");
var_dump($string);
$tmp = preg_replace('/\\$import\(("|\')' . $f . '("|\')\).*;/i', $string, $tmp);
var_dump($tmp);
$replace++;
}
$this->template = $tmp;
if($replace > 0){
$this->loadIncludes();
}
}

Within single quotes you can't use control characters like \r or \n, meaning you don't have to double-escape your $. Your \\$ can simply be \$.

Related

Insert some text after the second forward slash in a php string?

I've been working with this code
<?php
class PerchTemplateFilter_sol_en_cat_path extends PerchTemplateFilter {
public function filterAfterProcessing($value, $valueIsMarkup = false) {
// ORIGINAL STRING: solutions-en/rail-technologies/track-components/name-of-product
$mystring = $value;
$replace = ['solutions-en', '%2F'];
$str = '';
$oldstr = str_replace($replace, $str, $mystring);
$str_to_insert = 'XXX';
$findme = '/';
$pos = strpos($mystring, $findme); // I NEED THIS TO INSERT $str_to_insert AFTER THE SECOND FORWARD SLASH FOUND IN THE ORIGINAL STRING?
$value = substr_replace($oldstr, $str_to_insert, $pos, 0);
return $value;
// $value: /rail-technologies/track-components/XXX/name-of-product
// Insert string at specified position
// https://stackoverflow.com/questions/8251426/insert-string-at-specified-position
}
}
PerchSystem::register_template_filter('sol_en_cat_path', 'PerchTemplateFilter_sol_en_cat_path');
?>
My string is: solutions-en/rail-technologies/track-components/name-of-product
I want to end up with: /rail-technologies/XXX/track-components/name-of-product
XXX is only a placeholder value
I guess I need to do something with $pos to set where I want XXX to be added to the string.
I need to insert after the second forward slash, as the string may contain different text
The code above outputs this string: /rail-technoXXXlogies/track-components/ewosr-switch-lock
I can't seem to figure out how to insert XXX after the second forward slash.
Hope someone can provide some help.
How about explode to array, then implode the first two items.
Join with xxx and implode the rest?
function AddInTheMiddle($start, $where, $what){
$arr = explode("/", $what);
$str = implode("/", array_splice($arr,$start,$where)) . '/xxx/' . implode("/", $arr);;
return $str;
}
$str = 'solutions-en/rail-technologies/track-components/name-of-product';
$str = AddInTheMiddle(1, 2, $str);
https://3v4l.org/m98io
Thank you Andreas, your post gave me the nudge I needed. I did this in the end.
// ORIGINAL $value: solutions-en/rail-technologies/track-components/name-of-product
$str = explode("/", $value);
$value = $str[1] . '/' . 'solutions' . '/' . $str[2] . '/';
return $value;
// Removed: solutions-en
// Added: solutions
// $value: rail-technologies/solutions/track-components/name-of-product
I was able to add the name-of-product to the end of the new string elsewhere in my template.

How to remove anything character after the part of link from string?

I have make a try like this:
$string = "localhost/product/-/123456-Ebook-Guitar";
echo $string = substr($string, 0, strpos(strrev($string), "-/(0-9+)")-13);
and the output work :
localhost/product/-/123456 cause this just for above link with 13 character after /-/123456
How to remove all? i try
$string = "localhost/product/-/123456-Ebook-Guitar";
echo $string = substr($string, 0, strpos(strrev($string), "-/(0-9+)")-(.*));
not work and error sintax.
and i try
$string = "localhost/product/-/123456-Ebook-Guitar";
echo $string = substr($string, 0, strpos(strrev($string), "-/(0-9+)")-999);
the output is empty..
Assume there are no number after localhost/product/-/123456, then I will just trim it with below
$string = "localhost/product/-/123456-Ebook-Guitar";
echo rtrim($string, "a..zA..Z-"); // localhost/product/-/123456
Another non-regex version, but require 5.3.0+
$str = "localhost/product/-/123456-Ebook-Guitar-1-pdf/";
echo dirname($str) . "/" . strstr(basename($str), "-", true); //localhost/product/-/123456
Heres a more flexibility way but involve in regex
$string = "localhost/product/-/123456-Ebook-Guitar";
echo preg_replace("/^([^?]*-\/\d+)([^?]*)/", "$1", $string);
// localhost/product/-/123456
$string = "localhost/product/-/123456-Ebook-Guitar-1-pdf/";
echo preg_replace("/^([^?]*-\/\d+)([^?]*)/", "$1", $string);
// localhost/product/-/123456
This should match capture everything up to the number and remove everything afterward
regex101: localhost/product/-/123456-Ebook-Guitar
regex101: localhost/product/-/123456-Ebook-Guitar-1-pdf/
Not a one-liner, but this will do the trick:
$string = "localhost/product/-/123456-Ebook-Guitar";
// explode by "/"
$array1 = explode('/', $string);
// take the last element
$last = array_pop($array1);
// explode by "-"
$array2 = explode('-', $last);
// and finally, concatenate only what we want
$result = implode('/', $array1) . '/' . $array2[0];
// $result ---> "localhost/product/-/123456"

Function for each subfolder in PHP

I am new in PHP and can't figure out how to do this:
$link = 'http://www.domainname.com/folder1/folder2/folder3/folder4';
$domain_and_slash = http://www.domainname.com . '/';
$address_without_site_url = str_replace($domain_and_slash, '', $link);
foreach ($folder_adress) {
// function here for example
echo $folder_adress;
}
I can't figure out how to get the $folder_adress.
In the case above I want the function to echo these four:
folder1
folder1/folder2
folder1/folder2/folder3
folder1/folder2/folder3/folder4
The $link will have different amount of subfolders...
This gets you there. Some things you might explore more: explode, parse_url, trim. Taking a look at the docs of there functions gets you a better understanding how to handle url's and how the code below works.
$link = 'http://www.domainname.com/folder1/folder2/folder3/folder4';
$parts = parse_url($link);
$pathParts = explode('/', trim($parts['path'], '/'));
$buffer = "";
foreach ($pathParts as $part) {
$buffer .= $part.'/';
echo $buffer . PHP_EOL;
}
/*
Output:
folder1/
folder1/folder2/
folder1/folder2/folder3/
folder1/folder2/folder3/folder4/
*/
You should have a look on explode() function
array explode ( string $delimiter , string $string [, int $limit ] )
Returns an array of strings, each of
which is a substring of string formed
by splitting it on boundaries formed
by the string delimiter.
Use / as the delimiter.
This is what you are looking for:
$link = 'http://www.domainname.com/folder1/folder2/folder3/folder4';
$domain_and_slash = 'http://www.domainname.com' . '/';
$address_without_site_url = str_replace($domain_and_slash, '', $link);
// this splits the string into an array
$address_without_site_url_array = explode('/', $address_without_site_url);
$folder_adress = '';
// now we loop through the array we have and append each item to the string $folder_adress
foreach ($address_without_site_url_array as $item) {
// function here for example
$folder_adress .= $item.'/';
echo $folder_adress;
}
Hope that helps.
Try this:
$parts = explode("/", "folder1/folder2/folder3/folder4");
$base = "";
for($i=0;$i<count($parts);$i++){
$base .= ($base ? "/" : "") . $parts[$i];
echo $base . "<br/>";
}
I would use preg_match() for regular expression method:
$m = preg_match('%http://([.+?])/([.+?])/([.+?])/([.+?])/([.+?])/?%',$link)
// $m[1]: domain.ext
// $m[2]: folder1
// $m[3]: folder2
// $m[4]: folder3
// $m[5]: folder4
1) List approach: use split to get an array of folders, then concatenate them in a loop.
2) String approach: use strpos with an offset parameter which changes from 0 to 1 + last position where a slash was found, then use substr to extract the part of the folder string.
EDIT:
<?php
$folders = 'folder1/folder2/folder3/folder4';
function fn($folder) {
echo $folder, "\n";
}
echo "\narray approach\n";
$folder_array = split('/', $folders);
foreach ($folder_array as $folder) {
if ($result != '')
$result .= '/';
$result .= $folder;
fn($result);
}
echo "\nstring approach\n";
$pos = 0;
while ($pos = strpos($folders, '/', $pos)) {
fn(substr($folders, 0, $pos++));
}
fn($folders);
?>
If I had time, I could do a cleaner job. But this works and gets across come ideas: http://codepad.org/ITJVCccT
Use parse_url, trim, explode, array_pop, and implode

php turn line break into semicolon

I have a csv file with this:
software
hardware
educational
games
languages
.
.
.
I need a new csv file with:
software;hardware;educational;games;languages;....
How can I do that?
I'm doing:
<?php
$one = file_get_contents('one.csv');
$patterns =" /\\n/";
$replacements = ";";
$newone = preg_replace($patterns, $replacements, $one);
echo $newone;
file_put_contents('newone.csv', $newone );
?>
This adds the semicolon at the end of the line but the line break is still there
Surprisingly none of you mentioned file() that returns what he needs:
$cont = file('somefile.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
file_put_contents('somefile.csv',implode(';',$cont));
2 lines of code without using slow regex
OR
if you need less code, here with 1 line of code, the way i like !
file_put_contents(
'somefile.csv',
implode(
';',
file('somefile.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
)
);
Here is how you can do this.
Edit : tested this, works correct.
<?php
$row = 1;
$readHandle = fopen("in.csv", "r"); // open the csv file
$writeHandle = fopen("out.csv","w");
$subArr = array();
while (($data = fgetcsv($readHandle, 1000, "\n")) !== FALSE) {
$myStr = $data[0]; // this stores the zeroth column of each CSV row
$subArr[] = $myStr; // subArr contains all your words
}
fputcsv($writeHandle,$subArr,";"); // it creates a CSV with single line seperated by ;
fclose($readHandle);
fclose($writeHandle);
?>
I guess you could get a preg_match_all() to get every alphanumeric word surrounded by quotes into an array.
Then you just loop on that array and display them adding a semicolon.
as a one off, I would run home to mama...
perl -p -i -e 's|(.*)\n|$1;|m' one.cvs
Your file may have carriage returns. Try this:
$newone = str_replace("\r\n", ';', $one);
To cover all possibilities:
<?php
$file = 'data.csv';
file_put_contents($file, '"software"
"hardware"
"educational"
"games"
"languages"
');
$input_lines = file($file);
$output_columns = array();
foreach($input_lines as $line){
$line = trim($line); // Remove trailing new line
$line = substr($line, 1); // Remove leading quote
$line = substr($line, 0, -1); // Remove trailing quote
$output_columns[] = $line;
}
echo implode(';', $output_columns);
Beware: this code assumes no errors in input file. Always add some validation.
I suggest doing it like this:
<?php
$one = file_get_contents('one.csv');
$patterns ="/\\r?\\n/";
$replacements = ";";
$newone = preg_replace($patterns, $replacements, $one);
echo $newone;
file_put_contents('newone.csv', $newone );
?

remove a part of a URL argument string in php

I have a string in PHP that is a URI with all arguments:
$string = http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0
I want to completely remove an argument and return the remain string. For example I want to remove arg3 and end up with:
$string = http://domain.com/php/doc.php?arg1=0&arg2=1
I will always want to remove the same argument (arg3), and it may or not be the last argument.
Thoughts?
EDIT: there might be a bunch of wierd characters in arg3 so my prefered way to do this (in essence) would be:
$newstring = remove $_GET["arg3"] from $string;
There's no real reason to use regexes here, you can use string and array functions instead.
You can explode the part after the ? (which you can get using substr to get a substring and strrpos to get the position of the last ?) into an array, and use unset to remove arg3, and then join to put the string back together.:
$string = "http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0";
$pos = strrpos($string, "?"); // get the position of the last ? in the string
$query_string_parts = array();
foreach (explode("&", substr($string, $pos + 1)) as $q)
{
list($key, $val) = explode("=", $q);
if ($key != "arg3")
{
// keep track of the parts that don't have arg3 as the key
$query_string_parts[] = "$key=$val";
}
}
// rebuild the string
$result = substr($string, 0, $pos + 1) . join($query_string_parts);
See it in action at http://www.ideone.com/PrO0a
preg_replace("arg3=[^&]*(&|$)", "", $string)
I'm assuming the url itself won't contain arg3= here, which in a sane world should be a safe assumption.
$new = preg_replace('/&arg3=[^&]*/', '', $string);
This should also work, taking into account, for example, page anchors (#) and at least some of those "weird characters" you mention but don't seem worried about:
function remove_query_part($url, $term)
{
$query_str = parse_url($url, PHP_URL_QUERY);
if ($frag = parse_url($url, PHP_URL_FRAGMENT)) {
$frag = '#' . $frag;
}
parse_str($query_str, $query_arr);
unset($query_arr[$term]);
$new = '?' . http_build_query($query_arr) . $frag;
return str_replace(strstr($url, '?'), $new, $url);
}
Demo:
$string[] = 'http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0';
$string[] = 'http://domain.com/php/doc.php?arg1=0&arg2=1';
$string[] = 'http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0#frag';
$string[] = 'http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0&arg4=4';
$string[] = 'http://domain.com/php/doc.php';
$string[] = 'http://domain.com/php/doc.php#frag';
$string[] = 'http://example.com?arg1=question?mark&arg2=equal=sign&arg3=hello';
foreach ($string as $str) {
echo remove_query_part($str, 'arg3') . "\n";
}
Output:
http://domain.com/php/doc.php?arg1=0&arg2=1
http://domain.com/php/doc.php?arg1=0&arg2=1
http://domain.com/php/doc.php?arg1=0&arg2=1#frag
http://domain.com/php/doc.php?arg1=0&arg2=1&arg4=4
http://domain.com/php/doc.php
http://domain.com/php/doc.php#frag
http://example.com?arg1=question%3Fmark&arg2=equal%3Dsign
Tested only as shown.

Categories