How to trim all leading/trailing <br> code using php - 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";
}

Related

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));
?>

php substr in html dom

How can I use substr() in a HTML dom? I want keep all the html tags and just shorten the text.
$str = '<div>Today is a nice day</div>';
$part1 = preg_replace("/<a(.*?)>(.*?)<\/a>/i",substr('\\2', 0,10),$str).'...';
$part2 = preg_replace("/<a(.*?)>(.*?)<\/a>/i",'\\2',$str);
echo str_replace($part2,$part1,$str);// nothing change
// I need <div>Today is a...</div>
It could probably be a bit more robust, but this should do the trick:
$str = '<div>Today is a nice day</div>';
echo shortenLinks($str);
function shorten($matches) {
$maxlen = 10;
$str = $matches[2];
if (strlen($str) > $maxlen) {
return "<" . $matches[1] . ">" . substr($str, 0, $maxlen) . "...<";
} else {
return $matches[0];
}
}
function shortenLinks($str) {
$pattern = "/<(a\s+.*)>([^<]+)</";
return preg_replace_callback($pattern, "shorten", $str);
}

PHP string find and replace until last instance

I have a string in a DB table which is separated by a comma i.e. this,is,the,first,sting
What I would like to do and don't know how is to have the string outputted like:
this, is, the, first and string
Note the spaces and the last comma is replaced by the word 'and'.
This can be your solution:
$str = 'this,is,the,first,string';
$str = str_replace(',', ', ', $str);
echo preg_replace('/(.*),/', '$1 and', $str);
First use, the function provided in this answer: PHP Replace last occurrence of a String in a String?
function str_lreplace($search, $replace, $subject)
{
$pos = strrpos($subject, $search);
if($pos === false)
{
return $subject;
}
else
{
return substr_replace($subject, $replace, $pos, strlen($search));
}
}
Then, you should perform a common str_replace on text to replace all other commas:
$string = str_lreplace(',', 'and ', $string);
str_replace(',',', ',$string);
$words = explode( ',', $string );
$output_string = '';
for( $x = 0; $x < count($words); x++ ){
if( $x == 0 ){
$output = $words[$x];
}else if( $x == (count($words) - 1) ){
$output .= ', and ' . $words[$x];
}else{
$output .= ', ' . $words[$x];
}
}

Remove all the line breaks from the html source

Well I know obfuscation is a bad idea. But I want all of my html code to come in one long single line. All the html tags are generated through PHP, so I think its possible. I knew replacing \n\r from regular expression, but have no idea how to do this one. In case I am unclear here is an example
$output = '<p>
<div class="title">Hello</div>
</p>';
echo $output;
To be view in the source viewer as <p><div class="title">Hello</div></p>
Maybe this?
$output = str_replace(array("\r\n", "\r"), "\n", $output);
$lines = explode("\n", $output);
$new_lines = array();
foreach ($lines as $i => $line) {
if(!empty($line))
$new_lines[] = trim($line);
}
echo implode($new_lines);
You can try this perhaps.
// Before any output
ob_start();
// End of file
$output = ob_get_clean();
echo preg_replace('/^\s+|\n|\r|\s+$/m', '', $output);
This should, unless I messed up the regex, catch all output, and then replace all new line characters as well as all whitespace at the end and beginning of lines.
If you already have all output collected in a variable, you can of course just use the last line directly and skip the output buffering stuff :)
Worked for me:
$output = str_replace(array("\r\n", "\r", "\n"), "", $output);
You can do :
$output = '<p>'.
'<div class="title">Hello</div>'.
'</p>';
This way, $output won't contain any line jump.
This should also work :
$output = preg_replace(array('/\r/', '/\n/'), '', $output);
$output = preg_replace('!\s+!m', ' ', $output);
This is already well answered, but you may be able to do more than just trim spaces at both ends of each line:
First extract all text within quotes (you don't want to touch those), replace with a marker with a sequence number, store the sequence number with the text
Extract all text within <script></script> tags and do the same as step #1
Replace all white-space (including \n, \r) with spaces
Replace all >1 space sequences with 1 space
Replace all >_< with >< (_ = space)
Replace all _>, <_ and </_ with >, < and </ (_ = space)
Replace markers with the actual texts
This procedure can potentially compact the entire HTML file. This takes advantage of the fact that multiple white-space text inside HTML tags are intepreted as one single space.
This is a (as far as I have tested) working implementation of Stephen Chung's instructions. I'm not entirely convinced by number five, but have included it anyway.
Put the things you want to protect in the protected_parts array. Do it in order that you want them protected. If the starting and ending bits are different (as they would be in HTML tags), separate them by using a comma.
Also, I've no idea if this is the most optimised way of doing this, but it works for me and seems reasonably fast. Feel free to improve, etc. (Let me know if you do too!)
function MinifyHTML($str) {
$protected_parts = array("<pre>,</pre>", "\"", "'");
$extracted_values = array();
$i = 0;
foreach ($protected_parts as $part) {
$finished = false;
$search_offset = 0;
$first_offset = 0;
$startend = explode(",", $part);
if (count($startend) == 1) { $startend[1] = $startend[0]; }
while (!$finished) {
$first_offset = strpos($str, $startend[0], $search_offset);
if ($first_offset === false) { $finished = true; }
else {
$search_offset = strpos($str, $startend[1], $first_offset + strlen($startend[0]));
$extracted_values[$i] = substr($str, $first_offset + strlen($startend[0]), $search_offset - $first_offset - strlen($startend[0]));
$str = substr($str, 0, $first_offset + strlen($startend[0]))."$#".$i."$".substr($str, $search_offset);
$search_offset += strlen($startend[1]) + strlen((string)$i) + 3 - strlen($extracted_values[$i]);
$i++;
}
}
}
$str = preg_replace("/\s/", " ", $str);
$str = preg_replace("/\s{2,}/", " ", $str);
$str = str_replace("> <", "><", $str);
$str = str_replace(" >", ">", $str);
$str = str_replace("< ", "<", $str);
$str = str_replace("</ ", "</", $str);
for ($i = count($extracted_values); $i >= 0; $i--) {
$str = str_replace("$#".$i."$", $extracted_values[$i], $str);
}
return $str;
}
This is an improved function of the above. It adds text area protection and also anything that is a tag remains untouched.
I also removed strlen in the loop (its static).
This might run faster as a one pass filter to check for any of the protected parts. For such a small protected_parts array it's going to be more efficient than looping through the $str four times.
Also this doesn't fix: class = " " (the extra spaces between = and ") as its stuff inside the tags.
function MinifyHTML($str) {
$protected_parts = array('<pre>,</pre>','<textarea>,</textarea>', '<,>');
$extracted_values = array();
$i = 0;
foreach ($protected_parts as $part) {
$finished = false;
$search_offset = $first_offset = 0;
$end_offset = 1;
$startend = explode(',', $part);
if (count($startend) === 1) $startend[1] = $startend[0];
$len0 = strlen($startend[0]); $len1 = strlen($startend[1]);
while ($finished === false) {
$first_offset = strpos($str, $startend[0], $search_offset);
if ($first_offset === false) $finished = true;
else {
$search_offset = strpos($str, $startend[1], $first_offset + $len0);
$extracted_values[$i] = substr($str, $first_offset + $len0, $search_offset - $first_offset - $len0);
$str = substr($str, 0, $first_offset + $len0).'$$#'.$i.'$$'.substr($str, $search_offset);
$search_offset += $len1 + strlen((string)$i) + 5 - strlen($extracted_values[$i]);
++$i;
}
}
}
$str = preg_replace("/\s/", " ", $str);
$str = preg_replace("/\s{2,}/", " ", $str);
$replace = array('> <'=>'><', ' >'=>'>','< '=>'<','</ '=>'</');
$str = str_replace(array_keys($replace), array_values($replace), $str);
for ($d = 0; $d < $i; ++$d)
$str = str_replace('$$#'.$d.'$$', $extracted_values[$d], $str);
return $str;
}
You can't have <div> inside <p> - it is not spec-valid.
If you don't need to store it in a variable you can use this:
?><div><?php
?><div class="title">Hello</div><?php
?></div><?php

PHP - isolate first letter from a text

I have a set of articles, in which I want to style the first letter from each article (with CSS).
the articles usually start with a paragrah, like:
<p> bla bla </p>
So how could I wrap the first letter from this text within a <span> tag ?
Unless you need to do something extremely fancy, there's also the :first-letter CSS selector.
<?php
$str = '<p> bla bla </p>';
$search = '_^<p> *([\w])(.+) *</p>$_i';
$replacement = '<p><span>$1</span>$2</p>';
$new = preg_replace( $search, $replacement, $str );
echo $new."\n";
You can do this in all CSS.
CSS supports "Pseudo-Elements" where you can choose the first letter / first word and format it differently from the rest of the document.
http://www.w3schools.com/CSS/CSS_pseudo_elements.asp
There's a compatibility chart; some of these may not work in IE 6
http://kimblim.dk/css-tests/selectors/
you could add a Php span but might not be as clean
$s = " la la ";
$strip = trim(strip_tags($s));
$t = explode(' ', $strip);
$first = $t[0];
// then replace first character with span around it
$replace = preg_replace('/^?/', '$1', $first);
// then replace the first time of that word in the string
$s = preg_replace('/'.$first.'/', $replace, $s, 1);
echo $s;
//not tested
I've not found a versatile method yet, but a traditional code implementation (that may be slower) works:
function pos_first_letter($haystack) {
$ret = false;
if (!empty($haystack)) {
$l = strlen($haystack);
$t = false;
for ($i=0; $i < $l; $i++) {
if (!$t && ($haystack[$i] == '<') ) $t = true;
elseif ($t && ($haystack[$i] == '>')) $t = false;
elseif (!$t && !ctype_space($haystack[$i])) {
$ret = $i;
break;
}
}
}
return $ret;
}
Then call:
$i = pos_first_letter( $your_string );
if ($i !== false) {
$output = substr($s, 0, $i);
$output .= '<span>' . substr($s, $i, 1) . '</span>';
$output .= substr($s, $i+1);
}

Categories