Regexp搜索没有被包围

时间:2014-12-19 14:42:58

标签: javascript regex

我想找到所有不在引号字符内的%的出现。

例> "test% testing % '% hello' "会返回["%","%"]

查看另一个堆栈溢出线程,这是我发现的:

var patt = /!["'],*%,*!['"]/g

var str = "testing 123 '%' % '% ' "
var res = str.match(patt);

然而这让我无效。你有什么我应该做的提示吗?

Demo

4 个答案:

答案 0 :(得分:2)

您可以尝试使用以下正面预测断言的正则表达式。

> var s = "test% testing % '% hello' "
> s.match(/%(?=(?:[^']*'[^']*')*[^']*$)/g)
[ '%', '%' ]
> var str = "testing %"
undefined
> str.match(/%(?=(?:[^']*'[^']*')*[^']*$)/g)
[ '%' ]
> var str1 = "testing '%'"
undefined
> str1.match(/%(?=(?:[^']*'[^']*')*[^']*$)/g)
null

答案 1 :(得分:1)

试试这个:

var patt=  /[^"'].*?(%).*?[^'"]/g ;
var str = "testing 123 '%' % '% ' "
var res = str.match(patt);
console.dir(res[1]); // result will be in the 1st match group: res[1]

以下是在线测试的link

说明:

  • [^"'] - 除"'
  • 以外的任何字符
  • .*?任何字符(新行除外)任何时候或零次都不贪心。

更新

实际上,您必须检查 behing是否在%之前没有引号。 但是:

  

JavaScript regular expressions do not support lookbehinds

因此,除非应用更多限制,否则您无法识别"'%符号。

我建议用php或其他语言搜索(支持lookbehind)或强加更多条件。

答案 2 :(得分:1)

因为我不是正则表达的忠实粉丝,所以这是我的方法 重要的是什么在我的回答中,如果字符串中有尾随引号,其他答案将无效。换句话说,只有我的答案适用于有奇数引号的情况。

function countUnquoted(str, charToCount) {
    var i = 0,
        len = str.length,
        count = 0,
        suspects = 0,
        char,
        flag = false;

    for (; i < len; i++) {
        char = str.substr(i, 1);

        if ("'" === char) {
            flag = !flag;
            suspects = 0;
        } else if (charToCount === char && !flag) {
            count++;
        } else if (charToCount === char) {
            suspects++;
        }
    }

    //this way we can also count occurences in such situation
    //that the quotation mark has been opened but not closed till the end of string
    if (flag) {
        count += suspects;
    }

    return count;
}

据我所知,你想要计算这些百分号,所以没有必要把它们放在一个数组中。

如果你确实需要填充这个数组,你可以这样做:

function matchUnquoted(str, charToMatch) {
  var res = [],
      i = 0,
      count = countUnquoted(str, charToMatch);

  for (; i < count; i++) {
    res.push('%');
  }

  return res;
}

matchUnquoted("test% testing % '% hello' ", "%");

尾随报价

以下是字符串中尾随'(未关闭)的情况的比较。

> var s = "test% testing % '% hello' asd ' asd %"
> matchUnquoted(s, '%')
['%', '%', '%']
>
> // Avinash Raj's answer
> s.match(/%(?=(?:[^']*'[^']*')*[^']*$)/g)
['%', '%']

答案 3 :(得分:0)

使用此正则表达式:(['"]).*?\1|(%),第二个捕获组将包含不在单引号或双引号内的所有%符号。

故障:

(['"]).*?\1捕获单引号或双引号,后跟任何内容(懒惰),最多匹配单引号或双引号

|(%)只会抓取% ,如果它没有被替换的第一部分(即,如果它不在引号中),那么