otp icon indicating copy to clipboard operation
otp copied to clipboard

Regular expression replacement with a function

Open juhlig opened this issue 2 years ago • 1 comments

I rarely use regular expressions with Erlang. But when I do, I often would need a function to process matches and create replacements.

This PR extends re:replace/3,4 to accept a 2-ary function for the replacement. This function will be called with the entire match as the first and a list of subexpression matches as second argument. The value returned from the function will be inserted into the result.

A problem exists in case of regular expressions like this:

".(x)?(y)?"

When applied to a string like "axy", the function will be called with arguments <<"axy">> and [<<"x">>, <<"y">>]. When applied to "ax", the arguments will be <<"ax">> and [<<"x">>], ie the subexpression match list does not contain the optional-ish match related to (y). When applied to "ay", the arguments will be <<"ay">> and [<<>>, <<"y">>], ie the subexpression match list does contain the optional-ish match related to (x) as an empty binary.

I'm not sure how to handle this (and that is why it is not documented yet). The implementation for replacements using strings with back references inserts empty binaries if the match index does not exist in the actual match. For creating the subexpression match list for replacement via a function however, something like this is not possible. The easiest way out may be to recommend a catch-all clause that will return an empty binary, in the documentation.

juhlig avatar Aug 04 '22 11:08 juhlig

CT Test Results

       2 files       86 suites   33m 53s :stopwatch: 1 784 tests 1 736 :heavy_check_mark: 48 :zzz: 0 :x: 2 066 runs  2 016 :heavy_check_mark: 50 :zzz: 0 :x:

Results for commit 94191a89.

:recycle: This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

github-actions[bot] avatar Aug 04 '22 11:08 github-actions[bot]

Ok, great :) I applied your suggestions and will finish up the docs, squash the commits and write a more elaborate commit message tomorrow.

juhlig avatar Aug 23 '22 13:08 juhlig

@bjorng I documented the short subexpression list behavior as best as I could, what do you think? I also augmented the commit message as requested.

juhlig avatar Aug 24 '22 09:08 juhlig

There is some strange failure in the doc build, that seems to be unrelated to my changes :man_shrugging:

juhlig avatar Aug 24 '22 12:08 juhlig

There is some strange failure in the doc build, that seems to be unrelated to my changes.

Yes, it is unrelated to your changes.

bjorng avatar Aug 24 '22 12:08 bjorng

Thanks for your pull request.

bjorng avatar Aug 26 '22 05:08 bjorng