简体   繁体   中英

replace special characters within a block using regex

I need to replace all < and > between [code] block. I DO NOT want to select and replace all content within [code] I just want to select < and > within that and then temporary replace it to another characters. do other replacement and then back them to < > within [code].

solution that I use:

replace(/<(?=[^\[]*\[\/code\])/gi,"&_lt_;"); 
replace(/>(?=[^\[]*\[\/code\])/gi,"&_gt_;"); 

DO OTHER REPLACEMENT/CUSTOMIZATION HERE 

replace(/&_lt_;/gi,"<"); 
replace(/&_gt_;/gi,">"); 

only problem is that if content between [code] contain character [ it do not work before that character in block. how can I fix this?

example that works:

<b>
[code]
<form action="nd.php" method="post">
<b>
<strong>
[/code]
<b>

example that do not works:

<b>
[code]
<form action="nd.php" method="post">
<b>
$_POST[
<strong>
[/code]
<b>

EDIT: please only provide simple regex replace solution. I can not use callback function for this issue.

The accepted-answer for the linked question doesn't work for me for the " example that works ". However, the other answer does - it also works for the " example that does not work " (there was a typo though).

Try the following regex:

/(\[code\][\s\S]*?\[\/code\])|<[\s\S]*?>/g

In the replace() function, you would use:

.replace(/(\[code\][\s\S]*?\[\/code\])|<[\s\S]*?>/g, '$1'); 

EDIT
If I understand correctly, your end-goal is to keep all of the content within [code][/code] the same - but be able to do replacements on all HTML tags that are outside of these tags (which may or may not mean to fully strip the characters)?

If this is the case, there is no need for a long list of regexes; The above regex can be used (with a slight modification) and it can cover many cases. Combine the regex/replace with a callback function to handle your extra replacements:

var replaceCallback = function(match) {
    // if the match's first characters are '[code]', we have a '[code][/code]' block
    if (match.substring(0, 6) == '[code]') {
        // do any special replacements on this block; by default, return it untouched
        return match;
    }
    // the match you now have is an HTML tag; it can be `<tag>` or `</tag>`
    // do any special replacements; by default, return an empty string
    return '';
}

str = str.replace(/(\[code\][\s\S]*?\[\/code\])|(<[\s\S]*?>)/g, replaceCallback);

The one regex modification was to add a group around the html-tag section (the second part of the regex). This will allow it to be passed to the callback function.

UPDATE ( [code] isn't literal)
Per a comment, I've realized that the tag [code] isn't literal - you want to cover all BBCode style tags. This is just-as-easy as the above example (even easier in the callback). Instead of the word code in the regex, you can use [az]+ to cover all alphabetical characters. Then, inside the callback you can just check the very first character; if it's a [ , you're in a code block - otherwise you have an HTML tag that's outside a code block:

var replaceCallback = function(match) {
    // if the match's first character is '[', we have a '[code][/code]' block
    if (match.substring(0, 1) == '[') {
        // do any special replacements on this block; by default, return it untouched
        return match;
    }
    // the match you now have is an HTML tag; it can be `<tag>` or `</tag>`
    // do any special replacements; by default, return an empty string
    return '';
}

str = str.replace(/(\[[a-z]+\][\s\S]*?\[\/[a-z]+\])|(<[\s\S]*?>)/gi, replaceCallback);

Also note that I added an i to the regex's options to ignore case (otherwise you'll need [a-zA-Z] to handle capital letters).

Here's my edited answer. Sorry again.

str = str.replace(/(\[code\])(.*?)(\[\/code\])/gm,function(a,b,c,d) {
    return b + c.replace(/</g,'&lt;').replace(/>/g,'&gt;') + d;
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM