Jason28 Posted October 4, 2011 Share Posted October 4, 2011 I have spent hours trying to figure this out so I really hope you can make it work. I would imagine it is not that hard? I would like PHP to detect everything, spaces, tabs, letters, numbers, symbols, everything within brackets and tab them. So that an example: if($surl1 == "") { // blah blah $surl1 = "http://"; } while($row=mysql_fetch_array($result) { echo $row['name']; } would be converted into: if($surl1 == "") { // blah blah $surl1 = "http://"; } while($row=mysql_fetch_array($result) { echo $row['name']; } Please this has to be possible? I am really stressing and trying to make it work but I suck at Regex. Someone said use this: $string = preg_replace('#\{.*?\}#s', "/t", $string); but it doesn't work for me and it doesn't look correct, especially with just the \t there shouldn't there be a $1 or something in there too? Maybe it does work with further tweaking? Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/ Share on other sites More sharing options...
requinix Posted October 4, 2011 Share Posted October 4, 2011 You can't do this with just one expression. You need two. And some recursion. First regex grabs everything between sets of {}s. It needs to be recursive so it will match up {{}} properly. /\{(([^{}]*|(?R))*)\}/ Ignore the braces - just work with $1. The second regex applies one level of indentation. /^\s*\S/m => \t$0 The recursion is to start the process again on what you just found. Two tips: - Put this stuff into a function so you can call it recursively - Use preg_replace_callback and a closure/anonymous function (or just a regular function) for the first expression - Realize that your Allman formatting and indentation style makes things quite a bit easier Test your stuff on if ($condition) { if ($other_condition) { do_something(); } else { do_something_else(); } } Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275687 Share on other sites More sharing options...
Jason28 Posted October 4, 2011 Author Share Posted October 4, 2011 Thank you so much for your reply. Please do not get mad at me, but you are way smarter than me and I have no idea how to write out what you just said. Do you want me to do this? function blah($var) { $var = preg_replace_callback('/\{(([^{}]*|(?R))*)\}/', "$1", $var); $var = preg_replace_callback('/^\s*\S/m => \t$0', "$1", $var); return $var; } Sorry I do not speak the regex lingo and I tried reading tutorials but all they do is give me a migraine and when I think I understand it and put it to the test they do not work. It would be great if you could show me the code to use please that would really make my week. BTW all of this code appears in a text format as I am submitting it using a $_POST form and going to copy the result and paste it into my php files. Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275689 Share on other sites More sharing options...
gizmola Posted October 4, 2011 Share Posted October 4, 2011 Sorry I do not speak the regex lingo and I tried reading tutorials but all they do is give me a migraine and when I think I understand it and put it to the test they do not work. It would be great if you could show me the code to use please that would really make my week. BTW all of this code appears in a text format as I am submitting it using a $_POST form and going to copy the result and paste it into my php files. Regex's are difficult. I highly recommend getting your hands on an interactive testing tool. I use http://weitz.de/regex-coach/ but there are many others you will find if you do a google for "mac interactive regex tool" as an example. Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275728 Share on other sites More sharing options...
requinix Posted October 4, 2011 Share Posted October 4, 2011 Note: You'll need PHP 5.3+ for the code I'm posting. If you don't have that then say something. Or upgrade preg_replace_callback() will execute a function and use whatever that returns as the replacement string. Compare that with preg_replace()* which only allows you to give the same replacement string for everything. For example, you could use it to do something special with whatever text was found. You could make a BBCode tag like "[date]Y-m-d[/date]" that inserts a date according to PHP's date: $before = "[date]Y-m-d[/date]"; $after = preg_replace_callback('#\[date\]([a-z0-9/:-]+)\[/date\]#i', function($matches) { // $matches[1] is the format return date($matches[1]); }, $before); Basically, you can execute whatever code you want. In the spirit of learning, here's everything I said: function indent($code) { // first find all the sets of code blocks $formatted = preg_replace_callback('/\{(([^{}]*|(?R))*)\}/', function($matches) { // now we're replacing them // $matches[0] is the entire code block unformatted // $matches[1] is just the code inside $innercode = $matches[1]; // apply indentation $innercode = preg_replace('/^[ \t]*\S/m', "\t\$0", $innercode); // then apply indentation to any code blocks inside this one $innercode = indent($innercode); // return. don't forget to add the {}s back return "{" . $innercode . "}"; }, $code); return $formatted; } // test $code = if (\$condition) { if (\$other_condition) { do_something(); } else { do_something_else(); } } PHP; echo indent($code); if ($condition) { if ($other_condition) { do_something(); } else { do_something_else(); } } There is one difference: the second expression I posted (for adding indentation) should have [ \t] instead of \s. * Without /e. Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275750 Share on other sites More sharing options...
Jason28 Posted October 4, 2011 Author Share Posted October 4, 2011 Yay! Thanks so much requinix I will test it out shortly Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275785 Share on other sites More sharing options...
Jason28 Posted October 4, 2011 Author Share Posted October 4, 2011 Yeah I use hostgator and it looks like I am using PHP 5.2.17 and I get the error: Parse error: syntax error, unexpected T_FUNCTION with this line: $formatted = preg_replace_callback('/\{(([^{}]*|(?R))*)\}/', function($matches) { It also looks like it will error on this part too: }, $code); Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275786 Share on other sites More sharing options...
Jason28 Posted October 4, 2011 Author Share Posted October 4, 2011 Ok, interesting Hostgator told me to add a couple of lines of code to my htaccess to activate version 5.3.6 and that is the version it is using now. The error went away, but I am dead tired as I haven't been to sleep yet so I will test it out when I wake up. I do notice that you use: $code = <<<PHP if (\$condition) { if (\$other_condition) { do_something(); } else { do_something_else(); } } PHP; I am going to be posting text from a form and it is not PHP only but other languages and text as well. So would: $code = $_POST['code'] work with this function? Thanks a lot! Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275799 Share on other sites More sharing options...
requinix Posted October 4, 2011 Share Posted October 4, 2011 Yes, you can use whatever $code you want. But know that if it uses a different formatting and indentation scheme then you may get unusual results. You do plan to try to understand what I wrote, right? At least how it works, if not the syntax to get it to do that. Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275805 Share on other sites More sharing options...
Jason28 Posted October 5, 2011 Author Share Posted October 5, 2011 requinix are you extremely impressive wow, thanks so much it works People say that I know my stuff but I cannot touch you. Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275910 Share on other sites More sharing options...
Jason28 Posted October 5, 2011 Author Share Posted October 5, 2011 There is something weird though. I entered your function into the post and it indented it, but for some reason it breaks its function and doesn't work when indented: function indent($code) { // first find all the sets of code blocks $formatted = preg_replace_callback('/\{ (([^{}]*|(?R))*)\}/', function($matches) { // now we're replacing them // $matches[0] is the entire code block unformatted // $matches[1] is just the code inside $innercode = $matches[1]; // apply indentation $innercode = preg_replace('/^[ \t]*\S/m', "\t\$0", $innercode); // then apply indentation to any code blocks inside this one $innercode = indent($innercode); // return. don't forget to add the {}s back return "{" . $innercode . "}"; }, $code); return $formatted; } I also just noticed a problem that I am not sure can be resolved. Some variables that are between quotations like echo "Hello {$username}"; are converted into: echo "Hello { $username}"; If I had to guess on how to fix it, I would make it only indent after it detects an end paranthesis before the first curly bracket? Like if () { } it will see the ) { or ) (next empty line) { as the trigger? Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275913 Share on other sites More sharing options...
Jason28 Posted October 5, 2011 Author Share Posted October 5, 2011 Sorry, I had to make another post as I can no longer edit the one above. I promise this will be the last time I bother you Yes I see it tabbed after the first bracket in the function which is why it broke. Can you make it only tab if the first curly bracket has an end parenthesis before it? Also, it seems to tab even if there is already a tab within the parenthesis. Thank you so much for your time Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1275919 Share on other sites More sharing options...
silkfire Posted October 5, 2011 Share Posted October 5, 2011 You don't need brackets to echo variables in strings, mate: echo "Hello {$username}"; can be rewritten as: echo "Hello $username"; Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276031 Share on other sites More sharing options...
Jason28 Posted October 5, 2011 Author Share Posted October 5, 2011 You don't need brackets to echo variables in strings, mate: echo "Hello {$username}"; can be rewritten as: echo "Hello $username"; Yes I understand that thanks. I am using this function to clean up code of old scripts that do use brackets within quotes. I just need the function requinix created to only tab when the bracket comes after an end parenthesis and then it will be complete. Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276037 Share on other sites More sharing options...
Jason28 Posted October 5, 2011 Author Share Posted October 5, 2011 I tried adding a [^\)]* in there to only work after the end parenthesis and either I put it in the wrong spot or it is the wrong code since it didn't work Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276055 Share on other sites More sharing options...
requinix Posted October 5, 2011 Share Posted October 5, 2011 There is something weird though. I entered your function into the post and it indented it, but for some reason it breaks its function and doesn't work when indented: What? I also just noticed a problem that I am not sure can be resolved. Some variables that are between quotations like echo "Hello {$username}"; are converted into: echo "Hello { $username}"; You're starting to get into territory that regular expressions can still handle but only with great difficulty and complication. Try '/^\s*\{(([^"\'{}]*|"([^\\\\"]+|\\\\.)*"|\'([^\\\\\']+|\\\\.)*\'|(?R))*)\}/m' Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276141 Share on other sites More sharing options...
Jason28 Posted October 5, 2011 Author Share Posted October 5, 2011 Hello requinix, wow, that is some complex stuff It worked when I entered the function as a test in the field and made it work. However I tried pasting a whole file's worth of code like I did before and it resulted in a blank result. Your regex worked fine before, is it possible it can just be slightly edited to only work after detecting an end parenthesis ) or perhaps only outside of quotation marks or some other workaround? Thanks so much Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276145 Share on other sites More sharing options...
requinix Posted October 5, 2011 Share Posted October 5, 2011 Replace the ^ with (^|\)\s*). What code (to have indented) are you trying that isn't working? Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276166 Share on other sites More sharing options...
Jason28 Posted October 5, 2011 Author Share Posted October 5, 2011 Replace the ^ with (^|\)\s*). What code (to have indented) are you trying that isn't working? Hello, I wasn't sure if you meant replace all of the ^ or just the first one, so I tried both: '/(^|\)\s*)\s*\{(([(^|\)\s*)"\'{}]*|"([(^|\)\s*)\\\\"]+|\\\\.)*"|\'([(^|\)\s*)\\\\\']+|\\\\.)*\'|(?R))*)\}/m' No indention, and the second time I only replaced the first ^ '/(^|\)\s*)\s*\{(([^"\'{}]*|"([^\\\\"]+|\\\\.)*"|\'([^\\\\\']+|\\\\.)*\'|(?R))*)\}/m' It had a blank output. Would it be easier if I pm'ed you the whole code and the file I am trying to edit or would you rather we continue posting in this topic? Thanks Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276180 Share on other sites More sharing options...
xyph Posted October 5, 2011 Share Posted October 5, 2011 You're taking the wrong approach to this. You have to design a parser that is completely aware of the syntax. You then have to make sure there are no syntax errors that may break the script. You then have to split the code into it's individual parts without excess white space, and put it all back together, implementing the white spacing you want. It's very, very complex and I suggest using an IDE with this functionality built in to achieve this. Try writing a RegEx that will parse this as a string declaration. echo "this" . 'isn\'t very '.$easy." to do"; Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276208 Share on other sites More sharing options...
requinix Posted October 5, 2011 Share Posted October 5, 2011 xyph is right: the larger problem is knowing what can be indented and what cannot be, which requires a knowledge of the language and its grammar. The issue now is that apostrophes and {}s in comments are not ignored - the regex doesn't know that those are insignificant. For that matter, it would want to indent // todo: look for any {s in the code are are not inside comments or strings, // start a new indentation layer, and end the layer when the matching } appears Currently you can stop that with the \)\s* requirement, but the [^'"{}] is the main problem. That needs to be broken apart and that is very difficult. Impossible if you want it language-agnostic. In other words you've hit a dead end. From here you have to make something to indent specific languages (or at least languages with similar enough grammars, such as C/C++ and PHP). Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276223 Share on other sites More sharing options...
Jason28 Posted October 5, 2011 Author Share Posted October 5, 2011 Oh ok. Personally I do not mind that the comments do not work though. Well thanks a lot for all of the work you have put in this, that is the most free help I have ever received Quote Link to comment https://forums.phpfreaks.com/topic/248414-please-help-tab-everything-inbetween-brackets/#findComment-1276253 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.