Как сделать регулярное выражение не жадным?


227

Я использую JQuery. У меня есть строка с блоком специальных символов (начало и конец). Я хочу получить текст из этого блока специальных символов. Я использовал объект регулярного выражения для поиска в строке. Но как я могу сказать jQuery найти несколько результатов, если у них два специальных символа или больше?

Мой HTML:

<div id="container">
    <div id="textcontainer">
     Cuc chiến pháp lý gia [|cơ thử|nghim|] th trường [|test2|đây là test ln 2|] chng khoán [|Mỹ|day la nuoc my|] và ngân hàng đầu tư quyn lc nht Ph Wall mi ch bt đầ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 | 2â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 | lây là test lần 2 |] это правильно !. но я не очень понимаю это. Можете ли вы ответить на мой вопрос, почему?

Ответы:


492

Не жадные модификаторы регулярных выражений похожи на их жадные аналоги, но ?сразу после них следуют:

*  - zero or more
*? - zero or more (non-greedy)
+  - one or more
+? - one or more (non-greedy)
?  - zero or one
?? - zero or one (non-greedy)

29
может быть полезно отметить, что само ?по себе означает «один или ноль» (но это жадность!). Например, 'bb'.replace(/b?/, 'a') //'ab'и'bb'.replace(/c?/, 'a') //'abb'
Hashbrown

1
как там ничто не сравнится
Мухаммед Умер

1
@MuhammadUmer Я думаю, он предлагал это, потому что cне будет совпадать, но у вас есть ?, то есть 0 or 1, то оно будет соответствовать 0 number of c characters, следовательно, заменить его. Я понятия не имею, как это работает, потому что это не компилируется в любом движке регулярных выражений, который я пробовал 😢
Noctis

35

Вы правы в том, что жадность - это проблема

--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"

я копирую ваше регулярное выражение в мою работу, и результат: недопустимый квантификатор + \]) [нарушить эту ошибку] ​​var filterdata = takedata.match (/ (\ [[^ \]] ++ \]) /); \ n ( клопы + Firefox) что-то не так?
Rueta

@Rueta: очевидно, вкус Javascript не поддерживает притяжательные. Я отредактировал свой ответ, чтобы отразить этот факт. Вы можете просто использовать один +вместо двух.
полигенасмазочные материалы

1
Хотя атомарные группы могут использоваться вместо собственнических квантификаторов, JavaScript также не поддерживает атомарные группы. Но есть третий вариант, увидеть это: instanceof.me/post/52245507631/... -you can emulate atomic grouping with LookAhead. (?>a) becomes (?=(a))\1
Roland Pihlakas

2
Это ответ Java на вопрос JavaScript и Java! = JavaScript. Читатели, примите к сведению.
Рошамбо

3

Я верю, что это будет так

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

gв конце означает глобальный, поэтому он не останавливается на первом матче.


да, вы правы в / г. я только что выполнил свою работу с вашим ответом / g ^^. Но когда я делаю регулярные /(\[.+\])/g мой результат таков: [| cơ thử | nghiệm |] thị trường [| test2 | yây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc мой |] :(
Rueta
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.