Jump to content
  • Advertisement
Sign in to follow this  
Flyverse

PHP preg_replace_callback: Perform changes on string that is being used by the current regex in the callback

This topic is 1215 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys!

 

I'm currently doing some small kind of templating-system, and thus need to implement basic functionality such as simple loops and conditions. I'm using regular expressions since I don't really want to create a parser on my own.

My current problem is that I can't modify the string that is being used by the current regular expression action in its own callback (It's logical of course, but still).

 

Here is an example:

 

I have the string "{each42 test in tests}{hello} hello{end42}". My function is matching the first part of the loop "{each test in tests}" in a way that I know the ID of the tag (To avoid all those nested-tags problems that would require a parser), "test", and "tests".

I then extract the content of the loop "{hello} hello" by finding the end tag with the matching ID. Then I proceed to modify the extracted part, and eventually return it (Since this all happens in a preg_replace_callback callback function.). Now of course the loop-"header" is replaced by its final contents, but the original content plus the end tag still exists, and I can't delete them in the callback function itself since the regex-function just overrides them. What should I do to delete those remainders?

 

Thanks

 

 

Kind regards

Share this post


Link to post
Share on other sites
Advertisement

and I can't delete them in the callback function itself since the regex-function just overrides them


The return value of callback parameter in preg_replace_callback will replace the match:

<?php

$tbl = [
	'abc' => 'AAA',
	'def' => 'BBB'
];
print preg_replace_callback('/:(.+?):/',function($m) use ($tbl){
	return @$tbl[$m[1]] ?: $m[0];
},':abc: :def: :ghi:');

// displays:
// AAA BBB :ghi:

Share this post


Link to post
Share on other sites

Yeah, I know, but the problem was that it only replaces the match - And that I can't modify something that is not in the range of the match.

 

Solved it by changing my regex to include \g1: \{each\s(\w+)\sin\s(\w+)\s?}(.+?)\{end\g1}

Share this post


Link to post
Share on other sites

Just one more question about regexes... How do I match either "regex1" or "regex2" in the same expression? I tried doing ((regex1)|(regex2)), but it doesnt seem to work on regex101.com.

 

Here is the actual regex: "((\{\s?for(\w+)\s(\w+)\sin\s(\w+)\s?\}(.+?)\{end\g1\s?})|(\{\s?for(\w+)\s(\w+)\s?\=([0-9]+)\s?\;\s?(\w+)\s?(<|>|>=|<=|==|!=)\s?(\w+)\s?\;\s?(\+\+|\-\-|\|)(\w+)(\+\+|\-\-|\|)\s?\}(.+?)\{end\g1\s?}))" (Sorry for the bad formatting...)

 

And here are the two cases it should work with:

"{for0 index=0; i < 5; |i++}test{end0}"
"{for1 test in tests}test{end1}"
 
Weirdly enough, both expressions are working if they are alone. How do I make them work together?
 
Kind regards,
Flyverse

Share this post


Link to post
Share on other sites
See. This is how PHP got its start. And now look at the mess it's currently in. PHP7 is just barely getting a proper lexer and parser.


At this point you should stop using regular expressions and write a proper parser.
... or, you know, just use PHP:
 
<table>
<thead>
	<tr><?php
		foreach ( $fields as $field ) { ?>
			<th><?= $field ?></th><?php 
		} ?>
	</tr>
</thead>
<tbody><?php
	foreach ( $rows as $row ) { ?>
		<tr><?php
		foreach ( $fields as $field ) { ?>
			<td><?= $row[$field] ?></td><?php
		}?>
		</tr><?php
	} ?>
</tbody>
</table>
Edited by fastcall22

Share this post


Link to post
Share on other sites
The problem is that I have no real clue how parsers are working. I know that I have to convert the original input into tokens and then do stuff with it, but that is as far as my knowledge goes.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!