1

I have a string that is a PHP code example that contains the following snippet:

$data = array(
    'cKey1' => "dsfaasdfasdfasdfasdf",
    'cKey2' => "asdfasdfasdfadsfasdf",
    ...
);

Currently I'm just doing a str_replace on two hard-coded keys, but I need this to be more flexible now. These are the two regex I've come up with so far:

(?<=cKey1' => ).+(?=,)
(?<=cKey2' => ).+(?=,)

But, due to some people not using spaces, using double quotes, etc, this is not an ideal solution. Can someone point me in a better way to replace the values of cKey1 and cKey2 in a more efficient way?

Thanks!

2
  • 1
    use the tokenizer. php.net/manual/en/function.token-get-all.php Commented Feb 25, 2016 at 17:07
  • @anubhava: the output will be the same as the original string, just with made up values (similar to the example above) instead of real cKeys Commented Feb 25, 2016 at 18:26

2 Answers 2

1

You can use \K (match reset feature):

$re = array("/'cKey1'\s*=>\s*\K[^,]*/", "/'cKey2'\s*=>\s*\K[^,]*/");

$repl = array('"foo"', '"bar"')

echo preg_replace($re, $repl, $str);

Output:

$data = array(
    'cKey1' => "foo",
    'cKey2' => "bar",
    ...
);
Sign up to request clarification or add additional context in comments.

5 Comments

This almost did it for me. I get the contents of the code example using file_get_contents(), but I lose some of the opening lines for (likely due to the <?php). If I use htmlspecialchars() around file_get_contents() the data remains perfect, but your solution doesn't replace. Any ideas on that?
string(478) " "2e73625b5179497a423434736e", 'cKey2' => "036289E99EA6A48CBDA1DB247E", 'file' => 'V2/api/autoDoc/exampleAPI2.0.1.php' ); You can see it cuts off the opening tag and $data = array(
cat -vte V2/api/autoDoc/test.php <?php$ ^I$data = array($ ^I^I'cKey1' => "2e73625b5179497a423434736e",$ ^I^I'cKey2' => "036289E99EA6A48CBDA1DB247E",$ ^I^I'file' => 'V2/api/autoDoc/exampleAPI2.0.1.php'$ ^I);$ ^I$
yeah I'm not sure what is causing it.. The server the project is running on is 5.3, I tried it locally using mamp on 5.6 and the same thing happened. What version of PHP are you using?
1

Either use the tokenizer like @Casimir said or (if you insist on using a regex), you could come up with sth. like the following:

$regex = "~
            'cKey\d+'           # search for cKey followed by a digit
            .+?                 # match everything lazily
            ([\"'])             # up to a single/double quote (capture this)
            (?P<string>.*?)     # match everything up to $1
            \1                  # followed by the previously captured group
        ~x";
preg_match_all($regex, $your_string, $matches);

If you want to replace it with sth., consider using preg_replace_callback(), though you were not clear on your expected output.
See a demo on regex101.com. Thanks @WiktorStribiżew for the clarification in the comments.

5 Comments

When you define the boundaries as double or single quotes you should rely on lazy dot matching, not on the negated character class. Also, (\"|') => ([\"'])
@WiktorStribiżew: I value your feedback, so would you be so nice to say why using the lazy dot would be better in this case?
Check your regex with 'cKey1' => "dsfaasdfasdfasd'fasdf", input.
@WiktorStribiżew: Thanks Wiktor, appreciated and updated.
I like capturing group based solutions more than those PCRE specific only since they are portable. Still, maybe there is no sense using .+? since it is sure there is =>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.