2009-11-16 6 views
2

J'ai cette regex: ^\/\* pour vérifier et voir si un fichier contient ces deux caractères au début. Je suis en train d'itérer sur de nombreux fichiers source C++ essayant de voir lequel d'entre eux contient cela. Le problème est que si un fichier contient ceci:Pourquoi cette expression régulière ne fonctionne pas correctement?

#include <source.h> 

/* this is a comment */ 

cela correspond également à la regex. Je ne comprends pas pourquoi, puisque l'expression régulière n'a pas le drapeau multiligne.

Voici le code pour le regex:

multi = /^\/\*/ 

Pourquoi est-ce pas correspondant seulement au début du texte? Voici en gros tout ce que je fais:

data = File.read(filename) 
if data =~ multi 
    puts "file starts with multiline header" 
end 

Répondre

5

Dans Ruby ^ correspond après chaque saut de ligne. Utilisez \A pour correspondre seulement au début de la chaîne entière:

multi = /\A\/\*/ 
+1

Ce type de sux. Est-ce que c'est uniquement le comportement de Ruby, ou est-ce que toutes les langues ont ceci? – Geo

+0

La plupart des langues ont un commutateur appelé "mode multiligne" qui leur permet de se comporter comme ça, mais Ruby est le seul que je connaisse qui le fait par défaut. Le mode multiligne de Perl ressemble à '/^test/m' – Andomar

3

Utilisez \A (début de la chaîne) au lieu de ^ (début de la ligne).

L'interprétation de ^ n'est pas complètement cohérente entre les saveurs. Parfois, vous devez définir un modificateur de mode pour les chaînes multilignes, mais pas toujours. \A est cohérent (bien que non disponible dans toutes les versions, mais la plupart d'entre eux sont des exceptions, XML, POSIX ERE/BRE et quelques autres).

+0

Est-ce la même chose en Perl/Python? – Geo

+0

En Perl/Python, le comportement de '^' dépend des modificateurs de mode utilisés ('/ m' en Perl ou' re.MULTILINE' en Python). –

0

Je ne sais pas d'internals rubis, mais essayez ceci:

/^ [^ a-zA-Z # <>]/*/

La première partie assure que tout caractère valide est pas trouvé avant votre commentaire multiligne. S'il vous plaît, notez que [^ a-zA-Z # <>] est juste un exemple, vous devez le compléter avec une combinaison valide.

1

Pourquoi utiliser une expression régulière?

multi = "/*" 
data = File.read(filename) 
if data[0..2] == multi 
    puts "file starts with multiline header" 
end 
+0

Parce que des espaces supplémentaires peuvent être présents avant le début du commentaire. La regex était juste pour découvrir pourquoi Ruby se comportait comme ça. – Geo

Questions connexes