2016-09-05 11 views
0

Rubyを初めて使用し、テキストファイルを読み込んでパターンが一致するかどうかを確認する作業をしています。私は間違った行をどのように印刷するか分からない。Rubyパターンのマッチングと間違った行の印刷

例えば

が、これはテキストファイルです:

id: 1 food: apple, banana 
id: 2 food: orange 
ids: 3 food: apple, banana 
id: 4 food: hello, yellow 
id: 5food: apple, banana 

これは、次のような結果

id: 1 food: apple, banana 
id: 2 food: orange 
id: 4 food: hello, yellow 

を印刷し

File.open(ARGV[0]) do |f1| 
while line = f1.gets 
pattern = /id[:] [[:digit:]]+ food[:] [a-z,]+/ 
puts line.scan(pattern) 
end 

ファイルを読むしかし、私は間違った行を印刷したいです

ids: 3 food: apple, banana 
id: 5food: apple, banana 

パターンが一致していないかどうかをチェックして、フォーマットが正しくない行を印刷する方法を確認できません。

+0

私のRubyの教育にぽっかりと穴がありますように私は感じます。 'synset'とは何ですか? –

+0

私は前の答えがこのテストを適切にアンカーするために '/ \ A ... \ z /'を持っていたことは確かです。今すぐあなたがそれらを削除して、これは 'xid:...'と一致します。中間が良いからです。 – tadman

+0

私はあなたの正規表現 'pattern =/id [:] [[:digit:]] + synset [:] [a-z、] + /'を理解していません。まず、Rubyの正規表現の文脈で "synset"について聞いたことはありません。あなたは文書を提供できますか?また、各コロンを文字クラスに入れる必要はなく、 '' id: '"の後に一つのスペースしか許されず、 '' az ''は '' ,, ,,,, " –

答えて

1

scanは、一致するものがない場合は空の配列を返します。だからあなたはできるでしょう

File.open(ARGV[0]) do |f1| 
    while line = f1.gets 
    pattern = /id[:] [[:digit:]]+ synset[:] [a-z,]+/ 
    puts line if line.scan(pattern).empty? 
    end 
end 

別の方法で、クリーナー。 =~メソッドを使用して、行がパターンと一致するかどうかを確認できます。パターンが一致する場合は一致するインデックスを返し、一致しない場合はnilを返します。

File.open(ARGV[0]) do |f1| 
    while line = f1.gets 
    pattern = /id[:] [[:digit:]]+ synset[:] [a-z,]+/ 
    puts line unless line =~ pattern 
    end 
end 
1

は、ファイルが変数contentsに読み込まれたとします

contents =<<_ 
id: 1 food: apple, banana 
id: 2 food: orange 
ids: 3 food: apple, banana 
id: 4 food: hello, yellow 
id: 5food: apple, banana 
_ 

food:が必要な場合は、次の正規表現を使用することができます。

r =/
    \A     # match beginning of string 
    id:\s+    # match "id:" followed by > 0 spaces 
    \d+\s+    # match > 0 digits followed by > 0 spaces 
    food:\s+    # match "food:" followed by > 0 spaces 
    [[:alpha:]]+   # match > 0 (uppercase or lowercase) letters 
    (?:,\s+[[:alpha:]]+) # match a comma, > 0 spaces, > 0 letters in a non-capture group 
    *     # match > 0 instances of the aforementioned non-capture group 
    \n     # match newline  
    \z     # match end of string 
    /x     # free-spacing regex definition mode 

contents.each_line { |line| puts line if line !~ r } 

プリント

ids: 3 food: apple, banana 
id: 5food: apple, banana 
関連する問題