MyBB Community Forums

Full Version: Regex Help
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I've been working on making a plugin that hashes a value with the function and text a user provides.

Here is what I have so far:

function hash_message_parser(&$post)
{
	if(preg_match("/\[hash=(.*)\](.*)\[\/hash\]/is", $post['message']))
	{
		$validhashtypes = hash_algos();
		while(preg_match("/\[hash=(.*)\](.*)\[\/hash\]/is", $post['message']))
		{
			$hashtype = preg_replace("/\A(.*?)(\[hash=(.*)\](.*)\[\/hash\]){1}(.*?)\Z/is", "$3", $post['message'], 1);
			$hashstring = preg_replace("/\A(.*?)(\[hash=(.*)\](.*)\[\/hash\]\s{0,}){1}(.*?)\Z/is", "$4", $post['message'], 1);
			if(in_array($hashtype, $validhashtypes))
			{
				$replacementstring = hash($hashtype, $hashstring);
				$post['message'] = preg_replace("/\A(.*?)\[hash=(.*)\](.*)\[\/hash\](.*?)/is", "$1 $replacementstring $4", $post['message'], 1);
			}
			else
			{
				$post['message'] = preg_replace("/\[hash=(.*)\](.*)\[\/hash\]/is", "hash failed<br /> hash type: $hashtype<br />", $post['message'], 1);
			}
		}
	}
}

If it has no matches it works fine. If there is just one match it is fine. The issue is when there are two or more matches. Help.

Ex. http://teamdimensional.net/testforums/sh....php?tid=1
Perhaps preg_match_all() instead of preg_match()? I'm no good at regex either, but the function names seems to suggest the one you're using will only match one whereas preg_match_all() will do, well, all of them.
When I tried doing preg_match_all, I had no luck because it was giving an array in the foreach loop I had.
(2014-05-22, 02:52 PM)dragonexpert Wrote: [ -> ]When I tried doing preg_match_all, I had no luck because it was giving an array in the foreach loop I had.

You may need to modify the loop to support the syntax of the function, I didn't look into it much Toungue
Remove all those preg calls, ifs and while loops and use a single preg_replace_callback() instead.

And make your matches non-greedy. [hash=(.*)] may turn out to be [hash=x]bla bla bla[/hash]bla bla bla[hash=y] but there is no hash algorithm calles x]bla bla bla so ... fail
+1 on simplifying your regex. I assume your hash functions can contain only alphanumerics?

\[hash="?(?<hash_func>[\w]+)"?](?<hash_msg>.*)\[\/hash]

For example, in PHP this following code:

$input = "[hash=bcrypt]Test Data[/hash]";
preg_match_all("/\[hash="?(?<hash_func>[\w]+)"?](?<hash_msg>.*)\[\/hash]/", $input, $output);

Would produce the following in the $output array:

Array
(
    [0] => Array
        (
            [0] => [hash=bcrypt]Test Data[/hash]
        )

    [hash_func] => Array
        (
            [0] => bcrypt
        )

    [1] => Array
        (
            [0] => bcrypt
        )

    [hash_msg] => Array
        (
            [0] => Test Data
        )

    [2] => Array
        (
            [0] => Test Data
        )

)