Regex选择不起作用

Regex selection not working

本文关键字:不起作用 选择 Regex      更新时间:2023-09-26

我有一个脚本,可以自动格式化提词器的脚本。它应该把所有的东西都大写(除了某些例外)。然而,它也应该只保留带角括号或方括号中的任何内容,以及括号。

这是我创建的代码:

<script>
String.prototype.smartUpperCase = function(){
    var pattern = /(.*?[a-z][A-Z])(.*)/g;
    if(pattern.test(this)){
        return this.replace(pattern,function(t,a,b){
            return a+b.toUpperCase();
        });
    }
    else{
        return this.toUpperCase();
    }
}
String.prototype.regexEscape = function(){ return this.replace(/['-'[']'/'{'}'(')'*'+'?'.'''^'$'|]/g, "''$&"); }
String.prototype.removeBrackets = function(){ return this.replace(/['<'>'[']'(')]/g, ""); }
String.prototype.format = function(returnValNoShow){
    text = this;
    orig = text; // for use in multi-line regex pattern
    text = text.replace(/('w+)/g,function(t,w){ return w.smartUpperCase(); }); // smart uppercase everything
    text = text.replace(/'d{1,2}[st|nd|rd|th]{2}/gi, function(m){ return m.toLowerCase(); } ); // for dates (1st, 2nd, etc. will be lowecase)
    // complicated regex -> find anything inside <>, [], () and inject the original string back in
    var pattern = /.*(?=[^'<]*'>|[^'[]*']|[^'(]*')).*/g;
    text = text.replace( pattern, function(match){
        console.log(match);
        if(match==""){ return ""; }
        var pattern2 = new RegExp(".*(?="+match.regexEscape()+").*", "gi");
        //console.log(orig.match(pattern2));
        return orig.match(pattern2)[0];
    });
    text = text.replace(/'&/g, "AND"); // switch & for and
    text = text.replace(/ +/g, " "); // replace multiple spaces with one
    text = text.replace(/'n{3,}/g, "'n'n"); // replace 3+ line breaks with two
    text = text.replace(/'}'n{2,}/g, "}'n"); // don't allow empty line after name
    text = text.replace(/'n{2,}-+'n{2,}/g, "'n---'n"); // don't allow blank line between break (---)
    text = text.replace(/'n /g, "'n").replace(/ 'n/g, "'n"); // trim() each line
    text = text.trim(); // trim whitespace on ends
    return text;
}
function f() {
    document.getElementById("in").value = document.getElementById("in").value.format();
}
</script>

HTML很简单:

<textarea id="in" rows="40" cols="80">{NAME}
THANKS ____ AND ____. AS WE REPORTED LAST MONDAY, BATMAN VS SUPERMAN: DAWN OF JUSTICE CAME OUT THIS PAST WEEKEND AND IT SET SOME BOX OFFICE RECORDS.
{NAME}
(DDR) That's right ____. 'Batman v Superman' took huge $170 million at the box office. Audiences flocked to see the pairing of Batman (Ben Affleck) versus Superman (Henry Cavill) in the DC Comics film, which also introduced Wonder Woman (Gal Gadot).
{NAME}
IT'S THE BIGGEST MARCH OPENING WEEKEND EVER, EVEN BEATING 2012'S THE HUNGER GAMES' WHO BROUGHT IN $152.5 MILLION.
{NAME}
IN OTHER NEWS - SYRACUSE IS THE FIRST 10 SEED TO MAKE IT TO THE FINAL FOUR.
(ad lib)
</textarea>
<br/>
<input type="button" onclick="f()" value="Format"/>

99%的时间都是按预期进行的。然而,正如第二段所示,它有时没有任何作用。

(文本区域中的文本已经进行了格式化)

第一个问题是您的"在括号中查找东西"正则表达式:

var pattern = /.*(?=[^'<]*'>|[^'[]*']|[^'(]*')).*/g; //wrong

匹配整个字符串:模式的相关部分包含在"前瞻"断言中,该断言为零宽度,仅用作布尔值yes/no。您需要在消耗模式中主动匹配这些序列(同时也不要通过去掉.*来吃掉字符串的其余部分),这样它们才能被正确替换:

var pattern = /('([^'(]*')|'{[^'{]*'}|'[[^'[]*'])/g;

当您构建与原始文本匹配的替换模式时,会再次遇到此问题:

var pattern2 = new RegExp(".*(?="+match.regexEscape()+").*", "gi"); //wrong

这再次向前看match,但它被.*通配符序列包围,所以如果有匹配,它将是整个字符串。将其更改为:

var pattern2 = new RegExp(match.regexEscape(), "gi")

现在,当你进行替换时,它会像你希望的那样工作…这个演示显示了你的代码按预期工作。