The Little Guy Posted June 23, 2011 Share Posted June 23, 2011 I have this regexp: "/function(.+?)\(/" I want to replace the text that is inside the parenthesis. Here is an example string: function myFunction(){ alert("hi"); } I want to replace myFunction with html to make it bold Here is what I have, but it is also making the word "function" and "(" bold as well, which I don't want preg_replace("/function(.+?)\(/", '<span style="font-weight:bold;">$0</span>', $string) What can I do to just make "myFunction" bold? Quote Link to comment Share on other sites More sharing options...
silkfire Posted June 23, 2011 Share Posted June 23, 2011 Your logic is kinda wrong. You want everything inside the curly brackets to be bold, not the function name, right? Use this regex instead: $string = preg_replace('#{([^}]+)#', '{<span style="font-weight:bold;">$1</span>', $string); Quote Link to comment Share on other sites More sharing options...
The Little Guy Posted June 24, 2011 Author Share Posted June 24, 2011 no... I want the function name to be bold. Quote Link to comment Share on other sites More sharing options...
cags Posted June 24, 2011 Share Posted June 24, 2011 Either look into positive look-behind assersions, or cheat and do it the easy way, capture the word function as it's own capture group and make the replacement.. $1<span style="font-weight:bold;">$2</span> Quote Link to comment Share on other sites More sharing options...
The Little Guy Posted June 24, 2011 Author Share Posted June 24, 2011 Here is the method I went with: "/(function)(.+?)(\()/" '$1<span style="font-weight:bold;">$2</span>$3' I would like to try the positive look-behind assertion method, so I gave that a try, and came up with this: "/function(?<=.+?)/" but I get this error: Warning: preg_replace() [function.preg-replace]: Compilation failed: lookbehind assertion is not fixed length at offset 17 in /home/ryannaddy/beta.phpsnips.com/test.php on line 29 what could I do to fix it? Quote Link to comment Share on other sites More sharing options...
.josh Posted June 24, 2011 Share Posted June 24, 2011 The error is mostly self-explanatory. You can only do lookbehinds if the pattern you are matching is a fixed length. So for instance, you can lookbehind for "bob" but not "b[^ ]*". The main principle to understand here is that when you want to replace one thing with another, since preg_replace replaces everything that you match, you have to account for the "anchor" or "delimiter" parts of your pattern you use to isolate what you're trying to replace. So for instance, you are identifying the function name by matching for the "function" before it, and the "(" after it. Those are the "anchor/delimiter" parts of your pattern, what you use to identify the part you're trying to replace. You can accomplish it in several different ways. One way is to use zero-width assertion, which is basically a fancy way of saying match but do not actually consume or make part of the matched pattern. This will allow you to not have to worry about the "anchor/delimiter" parts of your pattern. The problem with that though is that look-behinds must be a fixed length. In your particular case, you can "probably" get away with using "function " as the look-behind pattern. But if you wanted to account for arbitrary space between "function" and the function name, it would no longer work, so IMO, using look-behind is not really the "safest" way to go. In general, the "safest" way to go is to just wrap your "anchor/delimiter" portions of your pattern in their own captured groups, and then use them in your replacement argument. So you mostly had it right in the first place. You just need to do a little bit of extra capturing, and use the right capture variables. Also, I changed it to use a negative char class instead of lazy match all because it's more efficient. $string = "function blah () {"; $string = preg_replace("~(function\s+)([^(]+)~i", '$1<span style="font-weight:bold;">$2</span>', $string); Quote Link to comment Share on other sites More sharing options...
salathe Posted June 24, 2011 Share Posted June 24, 2011 You could also just use magic. $string = preg_replace('/function\h+\K[^(\h]+/i', '<span class="function-name-of-awesomeness">$0</span>', $string); Quote Link to comment Share on other sites More sharing options...
.josh Posted June 24, 2011 Share Posted June 24, 2011 damn you and your \K salathe, damn you! Quote Link to comment Share on other sites More sharing options...
xyph Posted June 25, 2011 Share Posted June 25, 2011 This pattern enforces good function naming according to http://www.php.net/manual/en/functions.user-defined.php /function\s++([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)\s*+\(/ The function name will be the first (and only) capturing group Quote Link to comment Share on other sites More sharing options...
The Little Guy Posted June 27, 2011 Author Share Posted June 27, 2011 Mixing salathe's and xyph's code, I came up with this: /function\h+\K([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff])[^(\h]+/i What do you think? Quote Link to comment Share on other sites More sharing options...
.josh Posted June 27, 2011 Share Posted June 27, 2011 TBH I don't really think xyph's regex is necessary. What is your code for? Seems like a syntax highlighter...IMO it's not the job of your syntax highlighter to validate the function name. Or else, your markup regex and validation regex should be two separate things. Quote Link to comment Share on other sites More sharing options...
The Little Guy Posted June 27, 2011 Author Share Posted June 27, 2011 Okay, I removed the validation, since you feel it shouldn't be in a highlighter. Thanks for your guy's help it is awesome! Off topic: I downloaded the php source, hoping I could see how highlight_string works, but I can't seem to find the function in the source code, any suggestions on where I can find it? Quote Link to comment Share on other sites More sharing options...
salathe Posted June 28, 2011 Share Posted June 28, 2011 Look in Zend/zend_highlight.c (and Zend/zend_language_scanner.c if you want your mind melted). Quote Link to comment 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.