正则表达式在多个尾随的情况下无法正常工作]]]]

时间:2013-07-03 10:58:43

标签: javascript jquery regex

我要求用户可以在文本框中跳转到选项卡上[]中包含的下一个单词 例如 嗨[这]是一个例子。测试[这] 因此,当我的光标位于Hi并且我执行制表时,[this]中包含的字符会突出显示 当我再次执行Tabl时,下面的[an]中包含的下一个字符会突出显示。 这很好用

现在要求是包含[]之间的特殊字符的文本需要突出显示

案例1 :当我跟踪]]]时,它只突出显示前导[[[并忽略]]]]               例如             Screenshot where on a tab ignores training ]]]]

案例2 :如果多个尾随] ee [,则此]]]][测试],理想情况下为如果是单个标签,则应该转到[]中包含的下一个文字,但用户必须每次培训一次标签4次,以转到下一个[文字]                enter image description here

强烈的文字 代码是

$(document).ready(function() {
    $('textarea').highlightTextarea({
        color : '#0475D1',
        words : [ "/(\[.*?\])/g" ],
        textColor : '#000000'
    });
    $('textarea').live('keydown', function(e) {
        var keyCode = e.keyCode || e.which;
        if (keyCode == 9) {
            var currentIndex = getCaret($(this).get(0))
            selectText($(this), currentIndex);
            return false;
        }
    });
});

function selectText(element, currentIndex) {
    var rSearchTerm = new RegExp(/(\[.*?\])/);
    var ind = element.val().substr(currentIndex).search(rSearchTerm)
    currentIndex = (ind == -1 ? 0 : currentIndex);
    ind = (ind == -1 ? element.val().search(rSearchTerm) : ind);
    currentIndex = (ind == -1 ? 0 : currentIndex);
    var lasInd = (element.val().substr(currentIndex).search(rSearchTerm) == -1 ? 0
            : element.val().substr(currentIndex).indexOf(']'));
    var input = element.get(0);
    if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(ind + currentIndex, lasInd + 1 + currentIndex);
    } else if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', lasInd + 1 + currentIndex);
        range.moveStart('character', ind + currentIndex);
        range.select();
    }
}

function getCaret(el) {
    if (el.selectionEnd) {
        return el.selectionEnd;
    } else if (document.selection) {
        el.focus();
        var r = document.selection.createRange();
        if (r == null) {
            return 0;
        }
        var re = el.createTextRange(), rc = re.duplicate();
        re.moveToBookmark(r.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
    }
    return 0;
}

请让我知道处理上述两起案件

3 个答案:

答案 0 :(得分:2)

首先正则表达式应该是:

var rSearchTerm = /(\[.*?\]+)/;

使用+匹配模式末尾的一个或多个\]。此外,您不需要围绕正则表达式字面值new RegExp()

下一个问题是您使用包含以下内容的代码设置选择的结束位置:

element.val().substr(currentIndex).indexOf(']')

使用.indexOf(']')]之后找到第一个 currentIndex,而不是当前匹配中的最后一个<{1}}。如果您使用.match()而不是.search(),则可以找到最后一个,因为.match()返回一个数组,其中包含匹配的字符串的详细信息 - 您可以从中计算出的长度。匹配 - 并给出匹配的索引。

此外,反复调用element.val()element.val().substr()既可读又效率低 - 用值创建变量。并且多次调用.search()并使用所有这些?:三元表达式来决定应该将哪些索引变量调整为新值,这很难阅读和混淆。最后,我只是猜到了你要做的事情并将其重写为:

function selectText(element, currentIndex) {
    var rSearchTerm =  /(\[.*?\]+)/;
    var val = element.val();
    var matchStartPos, matchEndPos;
    var m = val.substr(currentIndex).match(rSearchTerm);
    if (!m){                             // if it didn't match
        currentIndex = 0;                // wrap back to the beginning
        m = val.match(rSearchTerm);      // and try to match again
    }
    console.log(m);
    if (m) {
        matchStartPos = m.index;
        matchEndPos = matchStartPos + m[0].length;
    } else {
        currentIndex = 0;
        matchStartPos = 0;
        matchEndPos = 0;
    }
    var input = element.get(0);
    if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(matchStartPos + currentIndex, matchEndPos + currentIndex);
    } else if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', matchEndPos + currentIndex);
        range.moveStart('character', matchStartPos + currentIndex);
        range.select();
    }
}

工作演示:http://jsbin.com/ewajoy/2/edit

答案 1 :(得分:1)

您需要调整正则表达式以匹配最后一个方括号。目前"/(\[.*?\])/g"只会匹配一个方括号。

试试这个"/(\[.*?\]*)/g"

答案 2 :(得分:1)

你可以使用这个正则表达式

(\[[^\[\]]*)+([^\[\]]*\])+

DEMO