I have the following output:
Item
Length : 130
Depth : 25
Total Area (sq cm): 3250
Wood Finish: Beech
Etc: etc
I want to remove the Total Area (sq cm): and the 4 digits after it from the string, currently I am trying to use str_replace like so:
$tidy_str = str_replace( $totalarea, "", $tidy_str);
Is this the correct function to use and if so how can I include the 4 random digits after this text? Please also note that this is not a set output so the string will change position within this.
You can practice php regex at http://www.phpliveregex.com/
<?php
$str = '
Item
Length : 130
Depth : 25
Total Area (sq cm): 3250
Wood Finish: Beech
Etc: etc
';
echo preg_replace("/Total Area \(sq cm\): [0-9]*\\n/", "", $str);
Item
Length : 130
Depth : 25
Wood Finish: Beech
Etc: etc
This will do it.
$exp = '/\(sq cm\): \d+/';
echo preg_replace($exp, '', $array);
Try with this:
preg_replace('/(Total Area \(sq cm\): )([0-9\.,]*)/' , '', $tidy_str);
You are looking for substr_replace:
$strToSearch = "Total Area (sq cm):";
$totalAreaIndex = strpos($tidy_str, $strToSearch);
echo substr_replace($tidy_str, '', $totalAreaIndex, strlen($strToSearch) + 5); // 5 = space plus 4 numbers.
If you want to remove the newline too, you should check if it's \n or \r\n. \n add one, \r\n add two to offset. Ie. strlen($strToSearch) + 7
Related
Assume a string is like
Section 1
Section 2 (after 1 line break)
Section 3 (after 2 line breaks)
Section 4 (after 4 line breaks)
Section 5 (after 1 line break)
My intention is to only allow N number of breaks and replace the other ones with SPACE in PHP. For example, if N=3 then the text above would be outputed like:
Section 1
Section 2 (after 1 line break)
Section 3 (after 2 line breaks) Section 4 (after 4 line breaks) Section 5 (after 1 line break)
My code is below but I am looking for a better way:
function limitedBreaks($str = '', $n = 5)
{
$str = nl2br($str);
$chars = str_split($str);
$counter = 0;
foreach ($chars as $key => $char) {
if ($char == "<br/>")
if ($counter > $n) {
$chars[$key] = ' ';
} else {
$counter += 1;
}
}
return implode($chars, ' ');
}
This really is a job better suited for regex than exploding and iterating.
$str = preg_replace('~\v+~', "\n\n", $str);
Here \v+ matches any number of vertical spaces, substituted with two \n newlines. You will get a standard one line gap between your content (non-linebreak-only) lines. This results in:
Section 1
Section 2 (after 1 line break)
Section 3 (after 2 line breaks)
Section 4 (after 4 line breaks)
Section 5 (after 1 line break)
If you want to only target more than N breaks, use e.g. \v{4,}, assuming EOL is \n, to normalize all instances of 4 or more newlines. If your file uses Windows EOL (\r\n), be aware that you need to double it up, or use (\r\n|\n){4,}, since \r and \n each are one match of \v.
That's the basic idea. Seeing as you want to replace 4+ newlines with horizontal space, merging the lines instead of normalizing line break quantity, you would simply:
$str = preg_replace('~(\r\n|\n){4,}~', " ", $str);
This would give you:
Section 1
Section 2 (after 1 line break)
Section 3 (after 2 line breaks) Section 4 (after 4 line breaks)
Section 5 (after 1 line break)
Here the gap with 4 or more EOLs was substituted with space and merged with the preceding line. The rest of the "acceptably spaced" lines are still in their places.
However it seems that you want to merge all subsequent rows into a single line after any gap of 4+ EOLs. Is that really the requirement? The first example I posted is a fairly standard operation for normalizing content with irregular linebreaks; especially "level items" like section headings!
OP: thanks for explaining your use case, makes sense. This can be regex-ed without loops:
$str = preg_replace_callback('~(\r\n|\n){4,}(?<therest>.+)~s', function($match) {
return ' ' . preg_replace('~\v+~', ' ', $match['therest']);
}, $str);
Here we capture (as named group therest) all the content that follows four or more linebreaks using preg_replace_callback, and inside the callback we preg_replace all vertical spaces in "the rest" with a single horizontal space. This results in:
Section 1
Section 2 (after 1 line break)
Section 3 (after 2 line breaks) Section 4 (after 4 line breaks) Section 5 (after 1 line break) Section 17 after a hundred bundred line breaks"
For convenience, here's the regex above wrapped in a function:
function fuse_breaks(string $str): string {
$str = preg_replace_callback('~(\r\n|\n){4,}(?<therest>.+)~s', function($match) {
return ' ' . preg_replace('~\v+~', ' ', $match['therest']);
}, $str);
return $str;
}
// Usage:
$fused_text = fuse_breaks($source_text);
Your example with N=3 shows either 4 line breaks – if the empty lines count –, or 2 line breaks.
To make things clearer this is a function limitedLines, which reduces the text to a specific amount of lines:
$str = "
line 1
line 2
line 3
line 4
line 5
line 6
";
function limitedLines(string $str = '', int $maxLines = 5): string {
$maxLines = $maxLines < 1 ? 1 : $maxLines;
$arr = explode("\n", trim($str));
while (count($arr) > $maxLines) {
$last = array_pop($arr);
$arr[array_key_last($arr)] .= ' ' . trim($last);
}
return implode("\n", $arr);
}
$result = limitedLines($str, 3);
print_r($result);
This will print:
line 1
line 2
line 3 line 4 line 5 line 6
I'm struggling with some regular expressions. What I want to do is find money amounts in a string, remove the €,$, or £ but keep the number, and then look to see if there is a 'b' or an 'm' - in which case write 'million platinum coins' or 'million gold coin' respectively but otherwise just put 'gold coins'.
I have most of that as a hack (see below) with the small problem that my regex does not seem to work. The money amount comes out unchanged.
Desired behaviour examples
I intend to leave the decimal places and thousands separators as is
$12.6m ==> 12.6 million gold coins
£2b ==> 2 million platinum coins
€99 ==> 99 gold coins
My code
Here is my non-working code (I suspect my regex might be wrong).
protected function funnymoney($text){
$text = preg_replace('/[€$£]*([0-9\.,]+)([mb])/i','\0 %\1%',$text);
$text = str_replace('%b%','million platnum coins',$text);
$text = str_replace('%m%','million gold coins',$text);
$text = str_replace('%%','gold coins',$text);
return $text;
}
I would greatly appreciate it if someone could explain to me what I am missing or getting wrong and guide me to the right answer. You may safely assume I know very little about regular expressions. I would like to understand why the solution works too if I can.
Using preg_replace_callback, you can do this in a single function call:
define ("re", '/[€$£]*(\.\d+|\d+(?:[.,]\d+)?)([mb]|)/i');
function funnymoney($text) {
return preg_replace_callback(re, function($m) {
return $m[1] .
($m[2] != "" ? " million" : "") . ($m[2] == "b" ? " platinum" : " gold") .
" coins";
}, $text);
}
// not call this function
echo funnymoney('$12.6m');
//=> "12.6 million gold coins"
echo funnymoney('£2b');
//=> "2 million platinum coins"
echo funnymoney('€99');
//=> "99 gold coins"
I am not sure how you intend to handle decimal places and thousands separators, so that part of my pattern may require adjustment. Beyond that, match the leading currency symbol (so that it is consumed/removed, then capture the numeric substring, then capture the optional trailing units (b or m).
Use a lookup array to translate the units to English. When the unit character is missing, apply the fallback value from the lookup array.
A lookup array will make your task easier to read and maintain.
Code: (Demo)
$str = '$1.1m
Foo
£2,2b
Bar
€99.9';
$lookup = [
'b' => 'million platinum coins',
'm' => 'million gold coins',
'' => 'gold coins',
];
echo preg_replace_callback(
'~[$£€](\d+(?:[.,]\d+)?)([bm]?)~iu',
function($m) use ($lookup) {
return "$m[1] " . $lookup[strtolower($m[2])];
},
$str
);
Output:
1.1 million gold coins
Foo
2,2 million platinum coins
Bar
99.9 gold coins
Your regex has a first full match on the string, and it goes on index 0 of the returning array, but it seems you just need the capturing groups.
$text = preg_replace('/[€$£]*([0-9\.,]+)([mb])/i','\1 %\2%',$text);
Funny question, btw!
Is this what you want?
<?php
/**
$12.6m ==> 12.6 million gold coins
£2b ==> 2 million platinum coins
€99 ==> 99 gold coins
*/
$str = <<<EOD
$12.6m
£2b
€99
EOD;
preg_match('/\$(.*?)m/', $str, $string1);
echo $string1[1] . " million gold coins \n";
preg_match('/\£(.*?)b/', $str, $string2);
echo $string2[1] . " million platinum coins \n";
preg_match('/\€([0-9])/', $str, $string3);
echo $string3[1] . " gold coins \n";
// output:
// 12.6 million gold coins
// 2 million platinum coins
// 9 gold coins
I have a text (.txt) file that contains text like this:
5 General
-10 Time Limits
-20 Scheduled Maintenance Checks
-30 Reserved
-40 Reserved
-50 Unscheduled Maintenance checks
6 DIMENSIONS and AREAS
7 LIFTING and SHORING
-00 General
-10 Jacking
-20 Shoring
8 LEVELING and WEIGHING
-00 General
-10 Weighing and Balancing
-20 Leveling
9 TOWING and TAXIING
-00 General
-10 Towing
-20 Taxiing
I want to replace the first space in each line with a comma (I'm trying to convert a txt file to a csv to prepare it for importing into a db). I started down the track of using strpos() function, but couldn't get my head around what to do next.
Bonus task: I also want a semi colon at the end of each line.
EDIT : Added actual data instead of sample data.
A simple preg_replace with limit will work:
$str = '5 Here is some text.';
echo preg_replace('/ /', ',', $str, 1);
// OUTPUT:
// 5,Here is some text.
With loop:
<?php
$str = array('5 Here is some text.', '5 Here is some text.','-10 Here is some text.','-20 Here is some text.','-30 Here is some text');
foreach ($str as $a) {
echo preg_replace('/ /', ',', $a, 1)."<br>";
}
// OUTPUT:
// 5,Here is some text.
// -10,Here is some text.
// -20,Here is some text.
// -30,Here is some text.
EDIT FOR YOUR NEW EDIT:
$str = "5 General
-10 Time Limits
-20 Scheduled Maintenance Checks
-30 Reserved
-40 Reserved
-50 Unscheduled Maintenance checks
6 DIMENSIONS and AREAS
7 LIFTING and SHORING
-00 General
-10 Jacking
-20 Shoring
8 LEVELING and WEIGHING
-00 General
-10 Weighing and Balancing
-20 Leveling
9 TOWING and TAXIING
-00 General
-10 Towing
-20 Taxiing";
$array = explode(PHP_EOL, $str);
foreach ($array as $a) {
echo preg_replace('/ /', ',', $a, 1)."<br>";
}
// OUTPUT:
/*
5,General
-10,Time Limits
-20,Scheduled Maintenance Checks
-30,Reserved
-40,Reserved
-50,Unscheduled Maintenance checks
6,DIMENSIONS and AREAS
7,LIFTING and SHORING
-00,General
-10,Jacking
-20,Shoring
8,LEVELING and WEIGHING
-00,General
-10,Weighing and Balancing
-20,Leveling
9,TOWING and TAXIING
-00,General
-10,Towing
-20,Taxiing
*/
You can use str_pos() and str_replace():
$csvData = array();
foreach (file("input.txt") as $line) {
$spacePos = str_pos($line, ' ');
$csvData[] = substr($line, 0, $spacePos) . ',' . substr($line, $spacePos + 1);
}
Or you can go to the more advanced preg_replace() to search and replace a pattern:
$csvData = array();
foreach (file("input.txt") as $line) {
$csvData[] = preg_replace('/^([^ ]+) /', '\1,', $line);
}
How can i only echo 5 lines?
<?php
$text = Here i have a long long long text about 20 lines;
echo $text;
?>
So and i want something like that.->
TEXTLINE 1
TEXTLINE 2
TEXTLINE 3
TEXTLINE 4
TEXTLINE 5
And than stop.
Code for the mentioned text of Harri (at least this would be my approach):
$strings = explode(" ", $text);
for($i=0; $i<$your_lines; $i++) {
echo $strings[$i] . " ";
}
Explode the string to array, then loop through the array until last line you want to print. Printh each line while looping the array.
when you need lines (not words) use
$lines = explode(PHP_EOL, $text);
Assuming the output is a web browser, then this is a display issue, since what you are referring to as "line" depends on the width/height of the container. (It's not very clear what you try to ask)
You can set a width and height on a div using css and use overflow hidden on that to achieve a result like the one you want
demo
http://jsfiddle.net/g5Y5c/
.mydiv {width:100px;height:100px;overflow:hidden;}
I want to add 300 spaces to a text file with PHP. I can't use   as you already knew (.txt format, not HTML), so how to do this?
So this code counts numbers as you can see, I need 300 white-spaces.
$spaces = 0; // will become 300 spaces
while ($spaces < 300)
{
$spaces++;
}
and for testing how many white-spaces I have I will use
substr_count($spaces, ' ');
Thanks
Instead of creating a loop to build them, just use the following
$padded_text = str_pad($some_text, 300, ' ', STR_PAD_LEFT);
Anything less than 300 chars big, gets spaces added, and depending where you want those spaces, you can try using STR_PAD_RIGHT or STR_PAD_BOTH. And if you have no characters at all, it will generate it full of 300 spaces, this will be faster than using a loop.
Now if you simply want to add 300 spaces (not pad it so that there will be less than 300 spaces) you'll want to use
$spaces = str_repeat(' ', 300);