Maintenant, quand vous avez mis à jour votre question, j'ai dû supprimer une grande partie de si bonne réponse :-)
Je suppose que le point principal de votre problème était que vous vouliez utiliser match[1]
au lieu de match
. L'objet renvoyé par la méthode Regexp.match
(MatchData
) peut être traité comme un tableau, qui contient toute la chaîne correspondante comme premier élément et chaque sous-requête dans les éléments suivants. Donc, dans votre cas, la variable match
(et match[0]
) est la chaîne entière correspondance (avec « == == page .. ») marques, mais vous vouliez que le premier sous-expression qui est caché dans match[1]
.
Maintenant à propos d'autres problèmes mineurs que je sens dans votre code. S'il vous plaît, ne soyez pas offensé au cas où vous savez déjà ce que je dis, mais peut-être que d'autres bénéficieront des avertissements.
La première partie de votre code (if File.exists? line
) a été vérifier si le fichier existe, mais votre code vient d'ouvrir le fichier (sans le fermer!) Et encore essayait d'ouvrir le fichier quelques lignes plus loin.
Vous pouvez utiliser cette ligne à la place:
next unless File.exists? line
Le deuxième chose est que le programme devrait être prêt à gérer la situation lorsque le fichier n'a pas de marques de page, il ne correspond pas au modèle. (La match
variables aurait alors nil
)
La troisième suggestionest qu'un petit modèle plus complexe pourrait être utilisé. L'actuel (/==Page 1==(.*)==Page 2==/m
) retournerait le contenu de la page avec la marque de fin de ligne comme premier caractère. Si vous utilisez ce modèle:
/==Page 1==\s*\n(.*)==Page 2==/m
alors la sous-expression ne contiendra pas les espaces blancs placés dans la même ligne que le texte « == Page 1 ==`. Et si vous utilisez ce modèle:
/==Page 1==\s*\n(.*\n)==Page 2==/m
alors vous serez sûr que la marque « == Page 2 == » commence dès le début de la ligne.
Et le quatrième problème est que très souvent les programmeurs (parfois moi y compris, bien sûr) ont tendance à oublier de fermer le dossier après ils l'ont ouvert. Dans votre cas, vous avez ouvert le fichier 'source', mais dans le code il n'y avait pas d'instruction source.close
après la boucle.La façon la plus sûre de la gestion des fichiers est en passant un bloc à la méthode File.open
, donc vous pouvez utiliser le formulaire suivant des premières lignes de votre programme:
File.open('list.txt') do |source|
source.readlines.each do |line|
... mais dans ce cas, il serait plus propre juste écrire:
File.readlines('list.txt').each do |line|
en prenant tout cela, le code pourrait ressembler à ceci (j'ai changé la line
variable fname
pour une meilleure lisibilité du code):
#!/usr/bin/env ruby -wKU
require 'fileutils'
File.readlines('list.txt').each do |fname|
fname.strip!
next unless File.exists? fname
text = File.read(fname)
if match = text.match(/==Page 1==\s*\n(.*\n)==Page 2==/m)
# The whole 'page' (String):
puts match[1].inspect
# The 'page' without the first two lines:
# (in case you really wanted to delete lines):
puts match[1].split("\n")[2..-1].inspect
else
# What to do if the file does not match the pattern?
raise "The file #{fname} does NOT include the page separators."
end
end
Pourriez-vous exprimer ce que vous voulez que le code fasse? Cela me ressemble: Je veux supprimer les 2 premières lignes de chaque fichier inclus dans une liste stockée dans un autre fichier. Est-ce exact? – mliebelt
Désolé - édité. Vous avez raison, vous voulez supprimer les deux premières lignes de chaque fichier dans ma liste. – chuckfinley
J'ai mis à jour la réponse. J'espère avoir trouvé votre problème :-) _ (notifier par un commentaire, car je ne sais pas si les demandeurs sont informés des mises à jour des réponses) _ – Arsen7