2017-10-12 7 views
2

Je le following regex:Emulation d'un lookbehind négatif de largeur inconnue dans PCRE

(?<=:)\s*\w+ 

Je veux extraire uniquement comp ou comp de la chaîne:

savedPosition: comp; 
CURLSCHET.NREC ('qwertyuiop'): noprotect; 

Je veux éviter les cas correspondant comme noprotect lorsqu'il y a un ( ou ) n'importe où avant le motif requis.

+0

Juste pour préciser: vous avez une chaîne multiligne et que vous voulez faire correspondre des mots spécifiques sur les lignes ne contenant pas '(' et ')'? Aussi, voulez-vous vraiment obtenir des correspondances vides, aussi? Je pense que vous avez besoin de '\ w +', pas de \ w * '. –

+0

Si la ligne est ': noprotect; (mot) ', voulez-vous extraire' noprotect'? Les solutions seront différentes pour les cas où une ligne entière ne devrait pas contenir '(' et ')' et quand il n'y aurait pas de '(' et ')' devant un 'mot' sur une ligne. –

+0

Wiktor Stribiżew, merci pour un conseil dans le premier commentaire. Oui, je veux extraire 'noprotect' si la ligne est': noprotect; (mot) ' – skaborik

Répondre

0

Un regard en arrière négatif de largeur inconnue est pas pris en charge par PCRE (ne .NET, il regarderait like this là-bas), mais vous ne pouvez extraire tous les matches sur chaque ligne avant la première ( ou ) en utilisant une combinaison de \G et \K opérateurs l'aide d'une classe de caractères nuls [^()] qui correspondrait à n'importe quel caractère mais ( et ).

Vous pouvez utiliser

(?m)(?:^|\G)[^()\n]*?:\h*\K\w+ 

Voir la regex demo

Détails

  • (?m) - mode MULTILINE sur
  • (?:^|\G) - début de correspondance d'une chaîne/ligne ou à la fin du match précédent
  • [^()\n]*? - tout autre que 0+ caractères (, ) et retour à la ligne, aussi peu que possible
  • : - deux points
  • \h* - 0+ horizontales
  • espaces blancs
  • \K - Match opérateur de réinitialisation qui élimine tout le texte apparié jusqu'ici
  • \w+ - 1 ou plusieurs caractères.
0

Vous devriez essayer alors:

[^\(\):]*:\s*(\w*) 

Explication:

  1. [^\(\):]*: tout de capture qui ne dispose pas (et (et:
  2. : folowed par:
  3. \s* suivi par zéro ou plusieurs caractères blancs
  4. \w* suivi par mot de zéro ou plus de longueur

Demo

Alternative:

Si vous ne voulez pas correspondre à la première partie, vous pouvez aussi essayer cette solution:

^(?=[^\(\):]*:).*:\s*\K(\w*) 

Alternative Demo

+0

Votre premier patron était une bonne idée, sauf qu'un début d'ancre de ligne est nécessaire. '(? m)^[^():] *: \ h * \ K \ w +' –

0

: *\K\w+

: matches the character : literally (case sensitive) 
* 
matches the character literally (case sensitive) 
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy) 
\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match 
\w+ 
matches any word character (equal to [a-zA-Z0-9_]) 
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)