In regex, zoek het einde van de tekenreeks of een specifiek teken

Ik heb een string. Het einde is anders, zoals index.php?test=1&list=ULof index.php?list=UL&more=1. Het enige wat ik zoek is &list=.

Hoe kan ik het matchen, of het nu in het midden van de string is of aan het einde? Tot nu toe heb ik [&|\?]list=.*?([&|$]), maar de ([&|$])onderdeel werkt niet echt; Ik probeer dat te gebruiken om &of het einde van de string te matchen, maar het einde van het stringgedeelte werkt niet, dus dit patroon komt overeen met het tweede voorbeeld, maar niet met het eerste.


Antwoord 1, autoriteit 100%

Gebruik:

/(&|\?)list=.*?(&|$)/

Houd er rekening mee dat wanneer u een uitdrukking voor haakjes gebruikt, elk teken erin (met sommigeuitzonderingen) letterlijk zal worden geïnterpreteerd. Met andere woorden, [&|$]komt overeen met de tekens&, |en $.


Antwoord 2, autoriteit 16%

Kortom

Alle beweringen met een breedte van nul binnen [...]verliezen hun betekenis van een bewering met een breedte van nul. [\b]komt niet overeen met een woordgrens (het komt overeen met een backspace, of, in POSIX, \of b), [$]komt overeen met een letterlijke $char, [^]is ofwel een fout of, zoals in ECMAScript regex flavour, een willekeurige char. Hetzelfde met \Z, \Z, \Aankers.

U kunt het probleem oplossen met een van de onderstaande patronen:

[&?]list=([^&]*)
[&?]list=(.*?)(?=&|$)
[&?]list=(.*?)(?![^&])

Als je moet controleren op het “absolute”, ondubbelzinnige string-end-anker, moet je onthouden dat het verschillende regex-smaken zijn, het wordt uitgedrukt met verschillende constructies:

[&?]list=(.*?)(?=&|$)  - OK for ECMA regex (JavaScript, default C++ `std::regex`)
[&?]list=(.*?)(?=&|\z) - OK for .NET, Go, Onigmo (Ruby), Perl, PCRE (PHP, base R), Boost, ICU (R `stringr`), Java/Andorid
[&?]list=(.*?)(?=&|\Z) - OK for Python

Overeenkomst tussen een tekenreeks en een enkele tekenreeks of het einde van een tekenreeks (huidig ​​scenario)

Het .*?([YOUR_SINGLE_CHAR_DELIMITER(S)]|$)patroon (voorgesteld door João Silva ) is nogal inefficiënt omdat de regex-engine eerst controleert op de patronen die rechts van het lazy-dot-patroon verschijnen, en alleen als ze niet overeenkomen, wordt het lazy-dot-patroon “uitgebreid”.

In deze gevallen wordt aanbevolen om negated character class(of uitdrukking tussen haakjesin de POSIX talk):

[&?]list=([^&]*)

Bekijk demo. Details

  • [&?]– een positieve tekenklasse die overeenkomt met &of ?(let op de relaties tussen tekens/tekenreeksen in een tekenklasse zijn OR-relaties)
  • list=– een subtekenreeks, tekenreeks
  • ([^&]*)– Vastleggen van groep #1: nul of meer (*) tekens anders dan &( [^&]), zoveel mogelijk

Controleren op de aanwezigheid van een enkele teken als scheidingsteken zonder deze terug te geven of aan het einde van de tekenreeks

De meeste regex-smaken (inclusief JavaScript beginnend met ECMAScript 2018) ondersteunen lookarounds, constructies die alleen waar of onwaar retourneren als er patronen overeenkomen of niet. Ze zijn cruciaal in het geval dat opeenvolgende overeenkomsten worden verwacht die met hetzelfde teken kunnen beginnen en eindigen (zie het originele patroon, het kan overeenkomen met een tekenreeks die begint en eindigt met &). Hoewel het niet wordt verwacht in een queryreeks, is het een veelvoorkomend scenario.

In dat geval kunt u twee benaderingen gebruiken:

  • Een positieve vooruitblik met een afwisseling met positieve tekenklasse: (?=[SINGLE_CHAR_DELIMITER(S)]|$)
  • Een negatieve vooruitblik met alleen een negatieve tekenklasse: (?![^SINGLE_CHAR_DELIMITER(S)])

De negatieve lookahead-oplossing is iets efficiënter omdat deze geen afwisselingsgroep bevat die de matchingprocedure ingewikkelder maakt. De OP-oplossing ziet eruit als

[&?]list=(.*?)(?=&|$)

of

[&?]list=(.*?)(?![^&])

Bekijk deze regex-demoen hier nog een.

Zeker, in het geval dat de achterste scheidingstekens multichar-reeksen zijn, zal alleen een positieve vooruitziende oplossing werken, aangezien [^yes]een reeks tekens niet negeert, maar de tekens binnen de klasse (dwz [^yes]komt overeen met elk teken behalve y, een s).

Other episodes