Як перетворити регулярний вираз на не жадібний?


226

Я використовую 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 | đâ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 |] це правильно !. але я насправді цього не розумію. Чи можете ви відповісти на моє питання?

Відповіді:


491

Не жадібні модифікатори регулярних виразів схожі на їх жадібні зустрічні частини, але з ними ?відразу ж:

*  - 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
як c нічого там не співпадало
Мухаммед Умер

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

Для зменшення зворотного відстеження використовуються заперечений клас символів та присвійний кількісний показник, і він, ймовірно, буде більш ефективним.

У вашому випадку, регулярний вираз буде таким:

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

На жаль, Jage regex не підтримує власні кількісні показники, тому вам просто доведеться робити:

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

Дивитися також


Швидкий підсумок

*   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 ( firebugs + 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в кінці означає глобальний, тому він не зупиняється на першому матчі.


так, ви праві в / г. я щойно зробив свою роботу з вашою відповіддю / г ^^. Але коли я роблю регулярні /(\ evidence.+\Sense)/g, мій результат такий: [| cơ thử | nghiệm |] thị trường [| test2 | đâ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.