0

I use regex to add markup to my website and I would like for **string** to only make the string bold if the string and asterisks are not between four brackets like so: [[**string**]] in this case the four asterisks and the string should stay the same and not dissapear or turn bold. I hope this is possible with regex.

For detecting when a string is between four asterisks I use this regex /**(.+?)**/ And for detecting when a string is between fourd brackets I use /[[(.+?)]]/s

2
  • 1
    Please supply a sample input string that represents the simpler and more complex types of substrings that you expect to encounter. Then show your exact desired output for that string. Commented Feb 7, 2021 at 11:41
  • 1
    So what exactly is your question? What error do you encounter? And please show us the code you already tried. This guide can help you with that. Commented Feb 8, 2021 at 3:56

3 Answers 3

1

You might use

(?<!\[\[|\*)\*\*(?!\*)(.+?)(?<!\*)\*\*(?!\*|]])

The pattern matches

  • (?<!\[\[|\*) Negative lookbehind, assert [[ or * to the left
  • \*\*(?!\*) Match ** and negative lokoahead to assert not * to the right
  • (.+?) Capture group 1, match 1+ chars as least as possible
  • (?<!\*)\*\* Negative lookbehind, assert not * to the left and match **
  • (?!\*|]]) Negative lookahead, assert not * or ]] to the right

Regex demo | Php demo

Another option might be matching all that you don't want and then making use of SKIP FAIL

(?:\[\[.*?]]|\*{3,}.*?\*+|\*+.*?\*{3,})(*SKIP)(*F)|\*\*(.+?)\*\*

Regex demo | Php demo

Sign up to request clarification or add additional context in comments.

Comments

0

Without seeing how much variability there is in your input string, I'd say you can simply match and discard the substrings that are double square brace and double asterisk wrapped and then match&capture the non brace wrapped substrings that are only asterisk wrapped.

There are fringe cases (like nested square braced substrings) where this will fail, but I don't know if they are reasonably likely to occur.

Code: (Demo)

$text = <<<TEXT
Text **bold** [[**not
bold**]]
TEXT;

echo preg_replace(
         '~\[{2}\*{2}.*?\*{2}]{2}(*SKIP)(*FAIL)|\*{2}(.*?)\*{2}~s',
         '<b>$1</b>',
         $text
     );

Output:

Text <b>bold</b> [[**not
bold**]]

Comments

0

What you need id to match only **string** not preceded by [ and should so :

  • (?<!\[) Negative lookbehinds to make sure tring not preceded by [
  • (?:[\*]{2}) string must be precded by two **
  • ([^\[\]\*]+) string match
  • (?:[\*]{2}) string must end with two **

(?<!\[)(?:[\*]{2})([^\[\]\*]+)(?:[\*]{2})

Demo

PHP code :

<?php
$str="[[**string**]]**string**[[**string**]]**string****string****string** [[**string**]]**string**[[**string**]]**string****string****string**[[**string**]]**string**[[**string**]]**string**[[**string**]][[**string**]]**string****string****string****string**abcd*abcdefg*abcdefgh**abcd***[**string**]]";
$pattern = '/(?<!\[)(?:[\*]{2})([^\[\]\*]+)(?:[\*]{2})/';
$replacement = '<b>$1</b>';
$str= preg_replace($pattern, $replacement,$str);
print $str;
?>

Comments

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.