正则表达式搜索未被包围

Regexp search not surrounded by

本文关键字:包围 搜索 正则表达式      更新时间:2023-09-26

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

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

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

var patt = /!["'],*%,*!['"]/g
var str = "testing 123 '%' % '% ' "
var res = str.match(patt);

但是这给了我空。你有什么提示我应该怎么做吗?

演示

您可以尝试以下基于正则表达式的积极展望断言。

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

试试这个:

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]

这是在线测试的链接。

解释:

  • [^"'] - 除"'之外的任何字符
  • .*?任何字符(换行符除外(任何时间或零次不贪婪。

更新

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

JavaScript 正则表达式不支持回溯

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

我建议使用 php 或其他语言(支持后看(进行搜索或施加更多条件。

由于我不是正则表达式的忠实粉丝,因此这是我的方法。
我的答案中重要的是,如果字符串中有一个尾随引号,其他答案将不起作用。换句话说,只有我的答案在引号数量奇数的情况下有效。

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)
['%', '%']

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

故障:

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

|(%) 仅当%没有被交替的第一部分(即,如果它不在引号中(时,才会捕获它