如何使正则表达式变成非贪婪的?

IT技术 javascript regex filter expression regex-greedy
2021-02-09 08:36:46

我正在使用 jQuery。我有一个带有特殊字符块(开始和结束)的字符串。我想从那个特殊字符块中获取文本。我使用正则表达式对象进行字符串内查找。但是,当有两个或更多特殊字符时,如何告诉 jQuery 查找多个结果?

我的 HTML:

<div id="container">
    <div id="textcontainer">
     Cuộc chiến pháp lý giữa [|cơ thử|nghiệm|] thị trường [|test2|đây là test lần 2|] chứng khoán [|Mỹ|day la nuoc my|] và ngân hàng đầu tư quyền lực nhất Phố Wall mới chỉ bắt đầu.
    </div>
</div>

和我的 JavaScript 代码:

$(document).ready(function() {
  var takedata = $("#textcontainer").text();
  var test = 'abcd adddb';
  var filterdata = takedata.match(/(\[.+\])/);

  alert(filterdata); 

  //end write js 
});

我的结果是:[|cơ thử|nghiệm|] thị trường [|test2|đây là test lần 2|] chứng khoán [|Mỹ|day la nuoc my|]但这不是我想要的结果:(。如何获得第 1 次的 [文本] 和第 2 次的 [演示]?


我刚刚在互联网上搜索信息后完成了我的工作^^。我制作这样的代码:

var filterdata = takedata.match(/(\[.*?\])/g);
  • 我的结果是:[|cơ thử|nghiệm|],[|test2|đây là test lần 2|] 这是对的!。但我真的不明白这一点。你能回答我的为什么吗?
3个回答

非贪婪的正则表达式修饰符就像它们贪婪的对应部分,但?紧跟在它们之后:

*  - zero or more
*? - zero or more (non-greedy)
+  - one or more
+? - one or more (non-greedy)
?  - zero or one
?? - zero or one (non-greedy)
如果您仍然需要支持 MSIE 11,最好知道它不支持srexexp标志——我首先认为 MSIE 不支持非贪婪修饰符,但真正的原因是s我的正则表达式中标志。
2021-03-16 08:36:46
@MuhammadUmer 我认为他的建议是因为c不会匹配,但您有?,即0 or 1,那么它将匹配0 number of c characters,因此替换它。我不知道它是如何工作的,因为它不能在我尝试过的任何正则表达式引擎中编译😢
2021-03-20 08:36:46
可能有用的是注意?它本身意味着“一或零”(但很贪心!)。例如'bb'.replace(/b?/, 'a') //'ab''bb'.replace(/c?/, 'a') //'abb'
2021-04-09 08:36:46
c 如何在那里匹配任何内容
2021-04-10 08:36:46

你是对的,贪婪是一个问题:

--A--Z--A--Z--
  ^^^^^^^^^^
     A.*Z

如果您想同时匹配两者A--Z,则必须使用A.*?Z?使*“不情愿”或懒惰)。

不过,有时有更好的方法来做到这一点,例如

A[^Z]*+Z

这使用否定字符类和所有格量词,以减少回溯,并且可能更有效。

在您的情况下,正则表达式将是:

/(\[[^\]]++\])/

不幸的是Javascript 正则表达式不支持所有格量​​词,所以你只需要做:

/(\[[^\]]+\])/

也可以看看


快速总结

*   Zero or more, greedy
*?  Zero or more, reluctant
*+  Zero or more, possessive

+   One or more, greedy
+?  One or more, reluctant
++  One or more, possessive

?   Zero or one, greedy
??  Zero or one, reluctant
?+  Zero or one, possessive

请注意,不情愿和所有格量词也适用于有限重复{n,m}结构。

Java 中的示例:

System.out.println("aAoZbAoZc".replaceAll("A.*Z", "!"));  // prints "a!c"
System.out.println("aAoZbAoZc".replaceAll("A.*?Z", "!")); // prints "a!b!c"

System.out.println("xxxxxx".replaceAll("x{3,5}", "Y"));  // prints "Yx"
System.out.println("xxxxxx".replaceAll("x{3,5}?", "Y")); // prints "YY"
尽管可以使用原子组代替所有格量词,但 JavaScript 也不支持原子组。但是还有第三种选择,请参见:instanceof.me/post/52245507631/... -you can emulate atomic grouping with LookAhead. (?>a) becomes (?=(a))\1
2021-03-16 08:36:46
这是针对 JavaScript 问题和 Java != JavaScript 的 Java 答案。读者请注意。
2021-03-23 08:36:46
我将你的正则表达式复制到我的工作中,结果是:无效量词 +\]) [打破这个错误] var filterdata = takedata.match(/(\[[^\]]++\])/);\n ( firebugs + Firefox)有什么问题吗?
2021-04-01 08:36:46
@Rueta:显然 Javascript 风格不支持所有格。我已经编辑了我的答案以反映这一事实。您可以只使用一个+而不是两个。
2021-04-08 08:36:46

我相信会是这样

takedata.match(/(\[.+\])/g);

g末意味着全球性的,所以它不会在第一场比赛停止。

是的,你是正确的 /g。我刚刚完成了你的回答/g ^^。但是当我做常规 /(\[.+\])/g 我的结果是: [|cơ thử|nghiệm|] thị trường [|test2|đây là test lần 2|] chứng khoán [|Mỹ|day la nuoc我的|] :(
2021-03-13 08:36:46