/ / Perl Regex - Obtenir l'offset comme numéro de ligne au lieu de la position du caractère dans le cas d'un MATCH - regex, perl, offset

Perl Regex - Récupère l'offset comme numéro de ligne au lieu de la position du caractère dans le cas d'un MATCH - regex, perl, offset

Je lis un fichier complet dans une chaîne, puis je fais une correspondance d'expression régulière comme ci-dessous:

if($str =~ m/$regex/gc) {
$offset = $+[0];
}

En utilisant ce code, je peux capturer la position où se termine la dernière correspondance réussie.

Maintenant, cela donnera la position comme numéro de caractère.

Existe-t-il un moyen d'obtenir le décalage en tant que numéro de ligne?

Ce que je fais pour l'instant, c'est que je compte le nombre de caractères de nouvelle ligne depuis le début de $str jusqu'à la fin $offset.

Je veux savoir s'il existe un moyen direct de capturer le numéro de ligne pour une correspondance d'expression régulière.

Réponses:

4 pour la réponse № 1

Contrairement à ce que l'on pourrait imaginer, La suggestion de Nahuel d'utilisation $. est en fait faisable dans ce cas.

En effet, on peut lire à partir de chaînes comme des fichiers en utilisant Perl:

use strict;
use warnings;

my $str = <<EOS;
spam
spam
spam
match
spam
match
EOS

open my $handle, "<", $str or die $!;

while ( <$handle> ) {

print $., "n" if /match/;
}

SORTIE

4
6

1 pour la réponse № 2

voir perldoc perlvar, variable spéciale $.

EDIT: après commentaire, désolé d'avoir lu trop vite

une autre solution, s'il y a beaucoup de correspondances, pourraitsoit de créer un tableau contenant le décalage des nouvelles lignes: $ a [0] -> décalage de la ligne 2, etc. puis d'approximer le numéro de ligne et enfin d'augmenter ou de diminuer pour trouver la ligne. Peut avoir un problème si la dernière ligne ne contient pas de caractère de nouvelle ligne.

# create an array with offset of new lines
@a=(0,0);push@a,$-[0]while$str=~/n/gc;

if($str =~ m/$regex/gc) {
$offset = $+[0];
# get an approximation of line
$l=int$offset*@a/$a[-1];
# increment or decrement
$l++while$a[$l+1]<$offset;
$l--while$a[$l]>$offset;
}

ÉDITER: pas testé, les changements initialisent @ a = (0,0) pour éviter +2 à la fin et sûr si correspondance sur la première ligne $ l ++ tandis que $ a [$ l + 1] $ offset et * @ a ajouté