?
Solved

Reg ex help

Posted on 2008-11-06
22
Medium Priority
?
173 Views
Last Modified: 2011-10-19
Need a regular expressoin to match line breaks occurring between a { and }.

Only remove them between the two characters, no throughout the string.

For a starting point I this:
//$content = preg_replace("#(\{)(?:[^\w]+)|(;)(?:[^\w}]+)#","$1$2",$content);

But it remove the line breaks after the @imports, and strips the second @


See code below...
$css = "
@import url('forms.css');
@import url('nav.css');
BODY {
color: #666;
font-family:Lucida Grande, Verdana, Sans-serif;
font-size: 11px;
background-color:#fff;
height: 100%;
}
BODY.popup {
padding: 10px;
background-color: #f6f6f6;
}
A {
color: #666;
}
H2 {
font-size: 16px;
font-weight: bold;
color: #3a3737;
}
H2.heading {
padding-bottom: 10px;
margin-bottom: 15px;
border-bottom: 1px solid #3a3737;
}
";
 
Should result in:
/*
@import url('forms.css');
@import url('nav.css');
BODY { color: #666; font-family:Lucida Grande, Verdana, Sans-serif; font-size: 11px; background-color:#fff; height: 100%; }
BODY.popup { padding: 10px; background-color: #f6f6f6; }
A { color: #666; }
H2 { font-size: 16px; font-weight: bold; color: #3a3737; }
H2.heading { padding-bottom: 10px; margin-bottom: 15px; border-bottom: 1px solid #3a3737; }
*/

Open in new window

0
Comment
Question by:qwertq
  • 12
  • 10
22 Comments
 
LVL 27

Expert Comment

by:ddrudik
ID: 22900197

function repfunc($match){
	return preg_replace('/\r\n/','',$match[0]);
}
$css=preg_replace_callback('#\{[^}]*\}#','repfunc',$css);

Open in new window

0
 

Author Comment

by:qwertq
ID: 22900224
This can't be done with one regex?  
0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22900256

$css=preg_replace('/(?=[^{}]*\})\r\n/','',$css);

Open in new window

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:qwertq
ID: 22900285
Thanks for getting it into one, but that doesn't appear to do anything.
0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22900316
Please check your code.
With this code:
<pre>
<?php
$css = "
@import url('forms.css');
@import url('nav.css');
BODY {
color: #666;
font-family:Lucida Grande, Verdana, Sans-serif;
font-size: 11px;
background-color:#fff;
height: 100%;
}
BODY.popup {
padding: 10px;
background-color: #f6f6f6;
}
A {
color: #666;
}
H2 {
font-size: 16px;
font-weight: bold;
color: #3a3737;
}
H2.heading {
padding-bottom: 10px;
margin-bottom: 15px;
border-bottom: 1px solid #3a3737;
}
";
echo htmlentities($css).'<hr>';
$css=preg_replace('/(?=[^{}]*\})\r\n/','',$css); 
echo htmlentities($css);
?>
 
I get this result:
 
@import url('forms.css');
@import url('nav.css');
BODY {
color: #666;
font-family:Lucida Grande, Verdana, Sans-serif;
font-size: 11px;
background-color:#fff;
height: 100%;
}
BODY.popup {
padding: 10px;
background-color: #f6f6f6;
}
A {
color: #666;
}
H2 {
font-size: 16px;
font-weight: bold;
color: #3a3737;
}
H2.heading {
padding-bottom: 10px;
margin-bottom: 15px;
border-bottom: 1px solid #3a3737;
}
--------------------------------------------------------------------------------
@import url('forms.css');
@import url('nav.css');
BODY {color: #666;font-family:Lucida Grande, Verdana, Sans-serif;font-size: 11px;background-color:#fff;height: 100%;}
BODY.popup {padding: 10px;background-color: #f6f6f6;}
A {color: #666;}
H2 {font-size: 16px;font-weight: bold;color: #3a3737;}
H2.heading {padding-bottom: 10px;margin-bottom: 15px;border-bottom: 1px solid #3a3737;}

Open in new window

0
 

Author Comment

by:qwertq
ID: 22900667
Are you on Windows? I see what's happening. I changed my document to have Windows line endings and it worked.
Is there anyway for this to work with Mac, Unix, and Window line ending?
0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22901042
changing \r\n to \r?\n should do it.
0
 

Author Comment

by:qwertq
ID: 22901254
Hmm, nothing.
$css=preg_replace('/(?=[^{}]*\})\r?\n/','',$css);
0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22901537
Paste your code with your string in the code in a comment here.

Result with new code:

@import url('forms.css');
@import url('nav.css');
BODY {
color: #666;
font-family:Lucida Grande, Verdana, Sans-serif;
font-size: 11px;
background-color:#fff;
height: 100%;
}
BODY.popup {
padding: 10px;
background-color: #f6f6f6;
}
A {
color: #666;
}
H2 {
font-size: 16px;
font-weight: bold;
color: #3a3737;
}
H2.heading {
padding-bottom: 10px;
margin-bottom: 15px;
border-bottom: 1px solid #3a3737;
}
--------------------------------------------------------------------------------
@import url('forms.css');
@import url('nav.css');
BODY {color: #666;font-family:Lucida Grande, Verdana, Sans-serif;font-size: 11px;background-color:#fff;height: 100%;}
BODY.popup {padding: 10px;background-color: #f6f6f6;}
A {color: #666;}
H2 {font-size: 16px;font-weight: bold;color: #3a3737;}
H2.heading {padding-bottom: 10px;margin-bottom: 15px;border-bottom: 1px solid #3a3737;}

Open in new window

0
 

Author Comment

by:qwertq
ID: 22901562
Sure. Here you go. Saving the file with Mac line endings.
<?php
 
 
$css = "
 
@import url('forms.css');
@import url('nav.css');
 
 
#layout {
                width: 1010px;
                }
        
                #layout #header,
                #layout #footer {
                        padding: 10px;
                        background-color: #3a3737;
                        font-size: 11px;
                        color: #fff;
                        }
        
                        #layout #header A,
                        #layout #footer A {
                                text-decoration: none;
                                color: #fff;
                                font-size: 13px;
                                font-weight: bold;
                                }
 
                        #layout #header .title {
                                font-size: 20px;
                                font-weight: bold;
                                }
        
                        #layout #header A {
                                margin-right: 5px;
                                padding: 3px 5px;
                                border: 1px solid #fff;
                                }
                                #layout #header A:hover {
                                        border: 1px solid #ccc;
                                        }
        
        
                #layout #content {
                        padding: 10px 0 10px 10px;
                        
                        }
        
                #layout #aside {
                        width: 290px;
                        float: left;
                        }
        
                #layout #main {
                        width: 690px;
                        float: right;
                        position: relative;
                        }";
 
echo 'ORIGINAL: <br/><textarea style="height: 400px; width: 600px;">'.$css.'</textarea>';
 
echo '<br/><br/><br/>';
 
// Remove tabs
$css = preg_replace('/\\t/', '', $css);
 
 
$css1 = preg_replace('/(?=[^{}]*\})\r?\n/','',$css);
 
$css2 = preg_replace('/(?=[^{}]*\})\r\n/','',$css);
 
echo '\R\N COMPRESSED: <br/><textarea style="height: 400px; width: 600px;">'.$css1.'</textarea><br/><br/>';
echo '\R?\N COMPRESSED: <br/><textarea style="height: 400px; width: 600px;">'.$css2.'</textarea>';
 
 
 
 
                        

Open in new window

0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22901611
I copied/pasted your code in a PHP script, ran it, copied the \R?\N COMP textarea, showed the regex code notation with my regex tester at http://www.myregextester.com and it shows the following (note I don't see any \r or \n within {} just \x20 (horizontal space).  It would seem your issue is not one with \r?\n.
^\x20\r\n@import\x20url('forms.css');\r\n@import\x20url('nav.css');\r\n\x20\r\n\x20\r\n#layout\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20width:\x201010px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\r\n\x20\x20\x20\x20\x20\x20\x20\x20\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#header,\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#footer\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2010px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background-color:\x20#3a3737;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color:\x20#fff;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\r\n\x20\x20\x20\x20\x20\x20\x20\x20\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#header\x20A,\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#footer\x20A\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20text-decoration:\x20none;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color:\x20#fff;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2013px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\r\n\x20\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#header\x20.title\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2020px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\r\n\x20\x20\x20\x20\x20\x20\x20\x20\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#header\x20A\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20margin-right:\x205px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:\x203px\x205px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#fff;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#header\x20A:hover\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#ccc;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\r\n\x20\x20\x20\x20\x20\x20\x20\x20\r\n\x20\x20\x20\x20\x20\x20\x20\x20\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#content\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2010px\x200\x2010px\x2010px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\r\n\x20\x20\x20\x20\x20\x20\x20\x20\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#aside\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20width:\x20290px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20float:\x20left;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\r\n\x20\x20\x20\x20\x20\x20\x20\x20\r\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20#layout\x20#main\x20{\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20width:\x20690px;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20float:\x20right;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20position:\x20relative;\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}$

Open in new window

0
 

Author Comment

by:qwertq
ID: 22901629
Then how come it works when I save the same php with windows line endings?
0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22901639
Please your file without windows line endings as something.txt, attach it to a comment here for testing.  I will test it on PHP5/Linux and view the result.  My guess is that whatever process you are using is leaving many spaces in the file and not \r\n within { } as you may have suspected.  Normally this issue wouldn't occur but what in your process is causing it I cannot hazard a guess, but I will look at the file you save without windows line endings to tell you what I see.
0
 

Author Comment

by:qwertq
ID: 22901656
Good idea. Here it is, thanks for the help.
css-test.txt
0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22901785
I saved the $css content (attached) as a .txt file, used this script to examine it:
It found the \r matches within {} but no \n matches at all in the file.

The css1.txt output file and the css.txt input files are both attached (the output file only as processed with the below script with with the \r replacement).  I believe it shows the \r removed from within the { } blocks.
<pre>
<?php
$css = file_get_contents('css.txt');
preg_match_all('/(?=[^{}]*\})\r/',$css,$matches);
echo print_r($matches,true);
preg_match_all('/\n/',$css,$matches);
echo print_r($matches,true);
$css = preg_replace('/(?=[^{}]*\})\r/','',$css);
$newfile = fopen('./saved/css1,txt',"w"); 
fwrite($newfile, $css); 
fclose($newfile);
echo 'done';
?>

Open in new window

css1.txt
css.txt
0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22901791
Usually UNIX text files will have \n but no \r characters as windows will have \r\n, your file however had \r but no \n, quite opposite what I would have expected.
0
 

Author Comment

by:qwertq
ID: 22901801
Is it possible to replace \r\n, \r, \n with one preg?
0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22901846
You can try to just use \r?\n? instead of \r?\n in my pattern but you still appear to have a number of other space characters (not \r) not replaced with {}.  BTW, I noticed you have '/\\t/' as a regex pattern in your code \\ would match literal \ and t would match literal t, if you want to remove tabs you would use '/\t/' instead.
0
 

Author Comment

by:qwertq
ID: 22905757
Your right, i need to strip multiple spaces too. I will add that. In the actual css there are tabs so i was not noticing that.

This works... kind of. If i try to replace it with a space it goes nuts thou. Is it matching every character?
$css = "
 
@import url('forms.css');
@import url('nav.css');
 
 
#layout {
			width: 1010px;
                }
        
                #layout #header,
                #layout #footer {
                        padding: 10px;
                        background-color: #3a3737;
                        font-size: 11px;
                        color: #fff;
                        }
        
                        #layout #header A,
                        #layout #footer A {
                                text-decoration: none;
                                color: #fff;
                                font-size: 13px;
                                font-weight: bold;
                                }
 
                        #layout #header .title {
                                font-size: 20px;
                                font-weight: bold;
                                }
        
                        #layout #header A {
                                margin-right: 5px;
                                padding: 3px 5px;
                                border: 1px solid #fff;
                                }
                                #layout #header A:hover {
                                        border: 1px solid #ccc;
                                        }
        
        
                #layout #content {
                        padding: 10px 0 10px 10px;
                        
                        }
        
                #layout #aside {
                        width: 290px;
                        float: left;
                        }
        
                #layout #main {
                        width: 690px;
                        float: right;
                        position: relative;
                        }";
 
echo 'ORIGINAL: <br/><textarea style="height: 400px; width: 600px;">'.$css.'</textarea>';
 
echo '<br/><br/><br/>';
 
// Remove tabs
$css = preg_replace('/\t/', '', $css);
 
 
$css = preg_replace('/(?=[^{}]*\})\r?\n?/',' ',$css);
 
echo 'COMPRESSED: <br/><textarea style="height: 400px; width: 600px;">'.$css.'</textarea>';
 
 
/*
Results in:
#layout {  w i d t h :   1 0 1 0 p x ;                                  }
 
*/

Open in new window

0
 
LVL 27

Accepted Solution

by:
ddrudik earned 1000 total points
ID: 22905778
You wouldn't replace them with spaces, just empty string.  I was remarking that you have many " " (\x20) characters in the file still after replacement that you will need to remove.

$css = preg_replace('/(?=[^{}]*\})\r?\n?/','',$css);
$css = preg_replace('/ {2,}/',' ',$css);
0
 

Author Comment

by:qwertq
ID: 22906050
Thanks that worked.

For anyone curious about the entire process I am doing I will include the code below.
			// Convert all referenced path to be absolute
 
			// Remove tabs
			$content = preg_replace('/\\t/', '', $content);
 
			// Remove occurances of multiple spaces
			$content = preg_replace('/ {2,}/',' ',$content);
 
			// Remove comments
			$content = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $content);
 
			// Remove line breaking between { }
			$content = preg_replace('/(?=[^{}]*\})\r?\n?/','',$content);
 
			// Remove empty lines
			$content = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $content);

Open in new window

0
 
LVL 27

Expert Comment

by:ddrudik
ID: 22906091
Thanks for the question and the points.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
The title says it all. Writing any type of PHP Application or API code that provides high throughput, while under a heavy load, seems to be an arcane art form (Black Magic). This article aims to provide some general guidelines for producing this typ…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.
Suggested Courses
Course of the Month17 days, 11 hours left to enroll

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question