2
votes

La fonction String.match () renvoie null même en cas de correspondance

J'essaie de faire correspondre une expression régulière avec certaines données dans un fichier, la fonction de correspondance renvoie cependant null même lorsque la correspondance existe clairement dans les données.

J'ai essayé les mêmes données et l'expression régulière sur RegExr et il montre une correspondance.

voici le code

Hi Alex how are you doing
hI dave how are you doing
Good by Alex
hidden agenda
Alex greeted Martha by saying Hi Martha

et voici le contenu du fichier

var fs = require('fs');
try {  
    var data = fs.readFileSync('File.txt', 'utf8');
    data = data.toString();
    var regex = /^(hi|hI|Hi|HI)\s[^dD].*?$/gm;
    var result = data.match(regex);
} catch(e) {
    console.log('Error:', e.stack);
}

J'ai utilisé les mêmes données sur RegExr et il montre la première ligne comme une correspondance. mais quand j'exécute le code ci-dessus sur ma machine, la variable de résultat reste nulle.

y a-t-il quelque chose qui me manque?

Voici quelques captures d'écran pendant que je déboguais le code dans vscode.

  1. contenu de la variable de données entrez la description de l'image ici

  2. état de la variable de résultat. entrez la description de l'image ici

  3. résultat de JSON.stringify entrez la description de l'image ici

Modifier. Résultats JSON.stringify

J'ai exécuté le programme sur cmd et de manière choquante, la chaîne a un espace devant.


19 commentaires

Pour info, votre expression régulière peut également être écrite sous la forme /^hi\s[^dedral.*/gmi


Votre code fonctionne bien pour moi. Comment savez-vous que le résultat est nul ? Rien dans le code que vous avez publié n'examine la valeur de result . Avez-vous un console.log () dans votre code actuel?


@nologin qui ne fera absolument aucune différence; il n'y a rien de mal avec un littéral regex.


Vous chargez probablement un mauvais fichier!


@Pointy J'exécute le code en mode débogage dans vscode, et il affiche le résultat comme nul après l'appel à correspondre


@pooyan Non, le fichier est correct, je peux voir le contenu de la variable de données.


@mightyWOZ, Il est donc également possible qu'il y ait de l'espace au début du fichier ou qu'il y ait un caractère inattendu (comme tab ou etc.) dans le fichier.


Et si vous l'exécutiez en dehors de l'EDI?


@Pointy même résultat, j'ai changé le code pour imprimer la variable de résultat et l'ai exécuté à partir de cmd, il imprime null.


@pooyan qu'en est-il des guillemets, les chaînes sont placées entre guillemets.


pourriez-vous faire console.log (JSON.stringify (data)) et nous dire ce que vous obtenez? (pas une capture d'écran s'il vous plaît)


Avez-vous enregistré le fichier avec BOM? Quelle est la valeur de data.codePointAt (0) ?


Juste en y jetant un coup d'œil, vos chaînes ont des espaces au début que vous ne tenez pas compte, mais je ne peux pas reproduire votre problème autrement.


Le ^ dans le modèle signifie que le modèle correspondra au début de la ligne. Vous devez avoir des caractères invisibles dans votre chaîne au début. Soit la nomenclature, soit certains caractères comme \ u200E


@JaredSmith mais pourquoi ne puis-je pas voir cet espace dans VIM


Vous pouvez simplement utiliser data = data.replace (/ ^ \ uFEFF /, '') pour supprimer la nomenclature si elle est là, puis exécuter votre regex. VIM est un éditeur de texte, il peut gérer la nomenclature. Identique au Bloc-notes. readFileSync laisse BOM dans les données lues et il appartient au programmeur de le gérer.


@ WiktorStribiżew oui c'était BOM, mais comment cela a-t-il été introduit dans mon fichier?


Certains éditeurs de fichiers suggèrent un choix "UTF-8 avec nomenclature" lors de l'enregistrement du fichier ou l'ont simplement dans les paramètres par défaut.


@mightyWOZ Il est déjà là. Il a été introduit par quelqu'un qui a enregistré le fichier en encodage UTF-8 avec BOM.


3 Réponses :


2
votes

L'espace dans la sortie JSON semble être BOM . Si tel est le cas, data.codePointAt (0) doit être 65279 .


0 commentaires

2
votes

Lorsque vous lisez un fichier avec fs.readFileSync , la nomenclature n'est pas supprimée des données lues et c'est au programmeur de le gérer. Voir fs.readFileSync (nom de fichier, 'utf8') ne supprime pas la nomenclature marqueurs .

Vous pouvez simplement utiliser

data = data.replace(/^\uFEFF/, '')

Cela supprimera la nomenclature si elle est là, puis vous pourrez exécuter votre regex.

Notez que vous ne voyez pas la nomenclature lors de l'ouverture de fichiers texte dans des éditeurs de texte, comme VIM, Bloc-notes, car ils peuvent gérer la nomenclature.


0 commentaires

2
votes

Le problème a été résolu à l'aide de la réponse de @ vsemozhetbyt ci-dessus et de nombreux commentaires utiles.

J'ajoute cette réponse pour aider si quelqu'un rencontre le problème à l'avenir.

pourquoi est-ce arrivé?

En raison d'un encodage incorrect, dans mon cas particulier, le File.txt était à l'origine File.jsp et j'ai changé son extension en .txt et l'ai enregistré. après cela, j'ai lu le fichier.txt qui contenait le même texte que JSP et j'ai fait la même expression régulière, cela fonctionnait bien et il n'y avait pas de nomenclature dans le fichier.

Un problème est apparu lorsque j'ai ouvert le fichier dans le bloc-notes et tout remplacé son contenu avec 5 lignes de texte affiché dans la question et l'a sauvegardé.

qu'est-ce que la nomenclature

Lisez cette excellente article

Comment j'ai supprimé la nomenclature

J'ai ouvert le fichier en mode binaire dans vim en utilisant

vim -b File.txt

et j'ai supprimé les trois premiers caractères (octets)


0 commentaires