【问题标题】:Positive look behind in JavaScript regular expressionJavaScript 正则表达式中的正面观察
【发布时间】:2022-01-18 21:51:22
【问题描述】:

我有一个文档,我需要从中提取一些数据。文档包含这样的字符串

Text:"How secure is my information?"

我需要提取文字 Text: 后面的双引号中的文本

How secure is my information?

如何在 Javascript 中使用正则表达式来做到这一点

【问题讨论】:

  • 这不是向后看(甚至不是向前看)。
  • 带有lookbehind的正则表达式会是什么样子?
  • @MattBall,你怎么看?可以匹配一个或多个字符,对Text:" 进行后视,对" 进行前瞻。
  • 我想我可以理解将lookbehind作为解决方案的想法,但它更适合对括号进行分组。即/Text: "([^"]*)"/

标签: javascript regex


【解决方案1】:

Lookbehind 断言最近已针对 JavaScript 完成,并将在 ECMA-262 规范的下一个出版物中发布。 Chrome 66 (Opera 53) 支持它们,但在撰写本文时没有其他主要浏览器。

var str = 'Text:"How secure is my information?"',
    reg = /(?<=Text:")[^"]+(?=")/;

str.match(reg)[0];
// -> How secure is my information?

旧版浏览器不支持 JavaScript 正则表达式中的lookbehind。您必须对像这样的表达式使用捕获括号:

var str = 'Text:"How secure is my information?"',
    reg = /Text:"([^"]+)"/;

str.match(reg)[1];
// -> How secure is my information?

不过,这不会涵盖所有后向断言用例。

【讨论】:

  • 但是如何从大文档中提取所有这些数据呢?说成数组什么的?
  • 嗯。当我测试上面的代码时,我得到一个未定义的。当我在没有索引 1 的情况下控制台 str.match(reg) 时,它会输出 ["Text:"How secure is my information?""] 想法?
  • @orangewarp:g 修饰符需要在我的答案中删除。
  • 酷。作品。为什么 g 修饰符会杀死捕获括号?我想知道,因为我可以想象一个字符串中可能有多个目标的场景。 str = 'Something &lt;id="12345"&gt; more things &lt;id="qwerty&gt;" ...' 如果我想要一个数组中的所有 id 值,您似乎想要使用 g 但捕获括号将消失。这里最好的方式是什么? reg = /id="([^"]+)"/g; -> ["id="12345"","id="qwerty""] -> 然后使用 /id="([^"]+)"/ 运行 foreach ?可以在一个正则表达式步骤中完成吗?
  • @orangewarp:这是匹配全局标志的标准行为。它基本上在幕后重复调用exec,在每次迭代中只返回结果数组中的第一个元素。最好的解决方案可能是运行自己的循环,调用RegExp.prototype.exec 并自己解析结果,或者使用search and don't replace 方法(两者或多或少相同,但后者在某些情况下提供了更多的便利)。
【解决方案2】:
string.match(/Text:"([^"]*)"/g)

【讨论】:

  • 如何避免匹配文本:在结果中?
  • string[0] 将始终具有完整的正则表达式匹配。 string[1] 将具有捕获的文本。如果正则表达式中有第二个捕获(括号),它将被放入字符串 [2] 等...
  • 我认为使用 /g 标志您只会获得所有匹配项的完整正则表达式匹配。
  • g 修饰符将查找页面上匹配的所有内容,而不仅仅是在第一个匹配项处停止。你说你有字符串(复数),所以我把 /g 修饰符放在那里。
【解决方案3】:

你可以这样做:

/Text:"(.*?)"/

解释:

  • Text:" :字面匹配
  • .*? :匹配任何内容 不贪心的方式
  • () : 捕捉比赛
  • " :匹配文字 "
  • / /:分隔符

【讨论】:

  • 你如何使用这个?你有什么背景吗?
  • 这是正则表达式,你应该使用它,例如 .match()
【解决方案4】:
<script type="text/javascript">
var str = 'Text:"How secure is my information?"';
var obj = eval('({'+str+'})')
console.log(obj.Text);
</script>

【讨论】:

  • 现代浏览器也有JSON.parse,可能比eval更受欢迎。
【解决方案5】:

我只是想补充一点:JavaScript 支持像(?&lt;= )(?&lt;! ) 这样的lookbehinds。

但它确实支持像 (?= )(?! ) 这样的前瞻。

【讨论】:

    【解决方案6】:

    如果你想完全避免使用正则表达式,你可以这样做:

    var texts = file.split('Text:"').slice(1).map(function (text) {
      return text.slice(0, text.lastIndexOf('"')); 
    });
    

    【讨论】:

      【解决方案7】:

      下面是一个例子,展示了如何处理这个问题。

      1) 给定这个输入字符串:

      const inputText = 
      `Text:"How secure is my information?"someRandomTextHere
      Voice:"Not very much"
      Text:"How to improve this?"
      Voice:"Don't use '123456' for your password"
      Text:"OK just like in the "Hackers" movie."`;
      

      2) 在文字 Text: 之后提取双引号中的数据,以便结果是一个包含所有匹配项的数组,如下所示:

      ["How secure is my information?",
       "How to improve this?",
       "OK just like in the \"Hackers\" movie."]
      

      解决方案

      function getText(text) {
        return text
          .match(/Text:".*"/g)
          .map(item => item.match(/^Text:"(.*)"/)[1]);
      }
      
      console.log(JSON.stringify(    getText(inputText)    ));
      

      运行代码片段以查看工作演示

      const inputText = 
      `Text:"How secure is my information?"someRandomTextHere
      Voice:"Not very much"
      Text:"How to improve this?"
      Voice:"Don't use '123456' for your password"
      Text:"OK just like in the "Hackers" movie."`;
      
      
      
      function getText(text) {
        return text
          .match(/Text:".*"/g)
          .map(item => item.match(/^Text:"(.*)"/)[1]);
      }
      
      console.log(JSON.stringify(    getText(inputText)    ));

      【讨论】:

        【解决方案8】:

        如果您像我一样,在研究与 Cloudinary gem 相关的错误时来到这里,您可能会发现这很有用:

        Cloudinary 最近发布了他们 gem 的 1.16.0 版本。在 Safari 中,这会因错误“无效的正则表达式:无效的组说明符名称”而崩溃。

        已提交错误报告。与此同时,我恢复到 1.15.0 并且错误消失了。

        希望这可以挽救某人的一生。

        【讨论】:

          猜你喜欢
          • 2012-06-12
          • 2014-10-23
          • 1970-01-01
          • 1970-01-01
          • 2012-01-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多