Based on the cases you listed, you can use this pattern:

  $ROEPatterns["/(\\(:FIXME:\\)|(?<![\t])\\bFIXME\\b)/"] = '(:FIXME:)';

Or the same broken into pieces, one with comments:

  $ROEPatterns["/(
    \\(:FIXME:\\)  # existing
    |              # or
    (?<![\t])      # not preceded by tab
      \\bFIXME\\b  # between non-word characters
    )/x"] = '(:FIXME:)';


The word boundary \b already matches start/end of text, newlines and spaces so you don't need to add these.

The expression has (?<![\t]) -- a rarely used RegEx feature called negative lookbehind to exclude the "[TAB]FIXME" case. This feature can only look for strings with fixed length so we need to also find the existing (:FIXME:) directives in order to not process them.

Alternatively we can test for ":FIXME" which may be part of "(:FIXME:)" or not. If there are no cases where you need to replace ":FIXME" with ":(:FIXME:)" then the pattern can be simpler:

  $ROEPatterns["/(?<![\t:])\\bFIXME\\b/"] = '(:FIXME:)';

that is "FIXME" not part of a word, and not preceded by TAB or colon.

I would advise enabling the "Preview changes" feature and pressing "Preview" to see how this behaves and to make sure nothing is forgotten or replaced by mistake.

You can read more about lookahead and lookbehind here:
  https://www.regular-expressions.info/lookaround.html

In case you wonder about the comments in the pattern, the /x modifier or why the \t is in brackets, see here:
  https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

Petko
--
If you upgrade :  http://www.pmwiki.org/Upgrades


On 10/01/2020 22:45, Robert Riebisch wrote:
As I'm not very familiar with RegExp it took my some hours on
<https://regexr.com/> to create an ROE Pattern to replace FIXME with
(:FIXME:)

        $ROEPatterns['/(^|\\n| )\\b(FIXME)\\b( ?)/'] = '\\1(:\\2:)\\3';

It seems to work for me now, but is it really right on edge cases?

My test cases:
#####
FIXME
^^^^^ At the beginning (match:)

Standalone (match):
FIXME

Already replaced (no match):
(:FIXME:)

In the middle of a word (no match):
fooFIXMEbar

Lowercase (no match):
fixme

Indented by 1 space (match):
 FIXME

Indented by 2 spaces (match):
  FIXME

Indented by 1 TAB (no match):
        FIXME

Indented and followed by spaces (match):
   FIXME

Somewhere in a text (match):
Foo FIXME bar.

End the end (match):
FIXME
#####

Cheers,
Robert

_______________________________________________
pmwiki-users mailing list
[email protected]
http://www.pmichaud.com/mailman/listinfo/pmwiki-users

Reply via email to