こんにちは。

Rubyで正規表現で見つかった箇所の文字列を置換するプログラムを書いているのですが、
一部うまく作動せず、その原因が分からないため質問させていただきました。

以下プログラムの置換の部分になります。
49 case text
50 when /株式数(株)\t貸借対照表計上額(千円)|株式数(株)\t貸借対照表計上額(千円)/
51 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1}株\t#{$3},000円\t"}
52 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
53 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t(\d{1})/){|s| "#{$1}株\t#{$3}円\t"}
54 when/百万円/
55 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)/) {|s| "#{$1}株\t#{$3},000,000円\t"}
56 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
57 when /株式数(株)\t貸借対照表計上額(百万円)/
58 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)/) {|s| "#{$1}株\t#{$3},000,000円\t"}
59 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
60 when /株式数(株)\t貸借対照表計上額(百万円)/
61 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1}株\t#{$3},000,000円\t"}
62 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
63 when /株式数(1000株)\t貸借対照表計上額(百万円)/
64 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1},000株\t#{$3},000,000円\t"}
65 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
66 when /株式数(1000株)\t貸借対照表計上額(百万円)/
67 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1},000株\t#{$3},000,000円\t"}
68 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
69 when/株式数(1000株)\t貸借対照表計上額(百万円)/
70 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1},000株\t#{$3},000,000円\t"}
71 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
72 when/株式数(1000株)\t貸借対照表計上額(百万円)/
73 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1},000株\t#{$3},000,000円\t"}
74 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
75 when/株式数(株) 貸借対照表計上額(百万円)/
76 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1},株\t#{$3},000,000円\t"}
77 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
78 when/株式数(株) 貸借対照表計上額(百万円)/
79 text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1},株\t#{$3},000,000円\t"}
80 text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
81 end

以下は今のプログラムで出てくる結果です。
1つ目の数字の後ろに「株」、2つ目の数字の後ろに「,000円」がついています。

ハ保有目的が純投資目的である投資株式の前事業年度及び当事業年度における貸借対照表計上額の合計額並びに当事業年度における受取配当金、売却損益及び評価損益の合計額(a)保有目的が純投資目的以外の目的である投資株式銘柄数58銘柄貸借対照表計上額の合計額6,915百万円(b)保有目的が純投資目的以外の目的である投資株式の保有区分、銘柄、株式数、貸借対照表計上額および保有目的(前事業年度)特定投資株式
前事業年度銘   柄株式数(株)貸借対照表計上額(百万円)保有目的
(株)髙島屋1,594,657株1,527,000円事業上の関係の維持・強化
トヨタ自動車(株)220,804株1,327,000円事業上の関係の維持・強化
(株)みずほフィナンシャルグループ3,295,570株642,000円取引銀行との関係の維持・強化
ヒューリック(株)638,400株552,000円事業上の関係の維持・強化
住友商事(株)229,198株294,000円事業上の関係の維持・強化
(株)三菱UFJフィナンシャル・グループ457,750株272,000円取引銀行との関係の維持・強化
阪急阪神ホールディングス(株)316,400株170,000円事業上の関係の維持・強化
(株)クラレ86,250株125,000円事業上の関係の維持・強化
積水ハウス(株)90,950株120,000円事業上の関係の維持・強化
東海旅客鉄道(株)10,000株112,000円事業上の関係の維持・強化
(株)池田泉州ホールディングス206,963株102,000円取引銀行との関係の維持・強化
帝人(株)425,000株99,000円事業上の関係の維持・強化
東レ(株)140,000株98,000円事業上の関係の維持・強化
(株)滋賀銀行181,020株96,000円取引銀行との関係の維持・強化
ダイニック(株)459,000株81,000円事業上の関係の維持・強化
三井住友トラスト・ホールディングス(株)187,568株80,000円取引銀行との関係の維持・強化
東日本旅客鉄道(株)10,000株75,000円事業上の関係の維持・強化
近畿日本鉄道(株)155,455株65,000円事業上の関係の維持・強化
長瀬産業(株)47,124株62,000円事業上の関係の維持・強化
ユニチカ(株)1,013,200株58,000円事業上の関係の維持・強化
(株)南都銀行154,532株58,000円取引銀行との関係の維持・強化
本田技研工業(株)12,245株46,000円事業上の関係の維持・強化
西日本旅客鉄道(株)10,000株42,000円事業上の関係の維持・強化
イオン(株)32,149株38,000円事業上の関係の維持・強化
コニカミノルタホールディングス(株)51,000株37,000円事業上の関係の維持・強化

本来ならば「,000円」ではなく「,000,000円」を付加して出力するはずなのですが
うまく動作せず「,000円」が付加されてしまっています。

どこを直せば正しく動作するでしょうか?
ご教授の程よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

http://oshiete.goo.ne.jp/qa/8839168.html
でも書いたのですが「理由をはっきりさせましょう」

プログラムを書く技術も必要ですが、それ以上に「正しく動作するかを確認する」「期待通りでない場合、その原因を調査解析し修正する」技術が大事です。

今回の例だと
・期待している when ではないwhen節が実行されている。または、どの条件にも当て嵌まらない。
・gsub!による置換が期待通りではない。
が主要因になりそうだ、と予想します。
そうなったら、デバッガや途中経過表示を使って
・textの内容と、実行されるwhenとが期待通りかを確認する
・gsub前と後のtextを比較して、期待通りの置換になっているかを確認する
もし、whenの不一致が理由なら、期待したwhenに合致するようにプログラムを変更します。
もし、gsubの置換が理由なら、期待した置換になるようにプログラムを変更します。

例えば
when /株式数(株)\t貸借対照表計上額(千円)|株式数(株)\t貸借対照表計上額(千円)/
STDERR.printf("when:%d:text:%s:\n",1,text)
text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t([1-9]\d{0,2}(,\d{3})*)\t/) {|s| "#{$1}株\t#{$3},000円\t"}
STDERR.printf("gsub後:%s:\n",text)
text.gsub!(/([1-9]\d{0,3})\t(\d{1})/){|s| "#{$1}株\t#{$2}円\t"}
STDERR.printf("gsub後:%s:\n",text)
text.gsub!(/([1-9]\d{0,2}(,\d{3})*)\t(\d{1})/){|s| "#{$1}株\t#{$3}円\t"}
STDERR.printf("gsub後:%s:\n",text)
とすれば、 このwhenにマッチしたときの処理の様子がわかります。


とりあえず気付いたのは
○whenは上から順番の評価され、最初にマッチしたものが使われます。
when/百万円/
が先に書いてあると、「百万円」を含むものは全てこちらになるため、 when /株式数(株)\t貸借対照表計上額(百万円)/ 等は絶対にマッチしません。

○もしかして、textはファイル全体ですか?
株式数(株)\t貸借対照表計上額(千円)
データ1
株式数(株)\t貸借対照表計上額(百万円
データ2
が全部一つになっているものだったら、 データ2の部分も「千円」として全部処理されます。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q.sub(/.+/,"aaaaaaa#{$&}"の置換開始行がずれるのなぜでしょうか?

f = ["1111111111111","2222222222222","3333333333333",]
f.each {|l|
p l.sub(/^.+$/, "aaaaaaa#{$&}bbbbbb")
p l
p ""
}
を Ruby1.8.7(2008-08-11patchlevel72)[i386-mswin32] で実行すると下記のように .sub(・・・) での置換開始行がずれました。なぜでしょうか?教えてくださいお願いします。
"aaaaaaabbbbbb"
"1111111111111"
""
"aaaaaaa1111111111111bbbbbb"
"2222222222222"
""
"aaaaaaa2222222222222bbbbbb"
"3333333333333"
""

Aベストアンサー

未検証。Rubyの経験殆どなし。

ですが,
http://www.ruby-doc.org/core/classes/String.html#M000831
>.sub(・・・) での置換開始行がずれました。
メソッド自体が,そういう仕様なんじゃないの?

If the method call specifies replacement, special variables such as $& will not be useful,
もし、メソッド呼び出しがreplacementを指定知る時,$&のような特殊な変数は役に立たないだろう。

>as substitution into the string occurs before the pattern match starts.
なぜなら,文字列への置き換えは【パターンマッチが始まる前】に行われるからだ。

However, the sequences \1, \2, etc., may be used.
\1,\2...等の変数が用いられるだろう。

#Howeverは訳すと今ひとつしっくり来ないので訳さず

未検証。Rubyの経験殆どなし。

ですが,
http://www.ruby-doc.org/core/classes/String.html#M000831
>.sub(・・・) での置換開始行がずれました。
メソッド自体が,そういう仕様なんじゃないの?

If the method call specifies replacement, special variables such as $& will not be useful,
もし、メソッド呼び出しがreplacementを指定知る時,$&のような特殊な変数は役に立たないだろう。

>as substitution into the string occurs before the pattern match starts.
なぜなら,文字列への置...続きを読む

Q/(.)(\d\d)+(.)/ =~ "123456"のとき、 p $

/(.)(\d\d)+(.)/ =~ "123456"のとき、 p $2とすると、"45"となるのはなぜですか?
p $2 #=>23 となると思っていました。
そして、いったい23はどうすれば後方参照できるのですか?

Aベストアンサー

(\d\d)+ は、2つの数字の1回以上の繰り返しですから、"23"と"45"にマッチします。
ですから、$2には最後にマッチした"45"を指すことになります。

もし対象の文字列が"12345"であれば、"23"と"45"にマッチさせると最後の(.)にマッチする文字が無くなってしまうので、$2は"23"になりますね($3は"4")

> いったい23はどうすれば後方参照できるのですか?

/(.)(\d\d)/ =~ "123456"
p $2

ではダメでしょうか?

Q{Ruby}ディレクトリ内の全てのファイルを操作

こんばんは。
最近Rubyでファイルのスクローリングをしているのですが、
以下のようなスクリプトを全てのファイルに適用したいと考えています。

1 fpath = '/home/edinet/E30479/S1002D1W/index.html'
2
3 text = ""
4
5
6 File.open(fpath).each do |f|
7 f.each_line do |line|
8
9 line.gsub!(/前事業年度特定投資株式/,"前事業年度")
10 line.gsub!(/当事業年度特定投資株式/,"当事業年度")
11
12 end
13 end
14
15
16 flag = nil
17 IO.foreach(fpath) do |line2|
18
19 case line2
20 when /保有目的が純投資目的以外/
21 flag = true
22 when /保有目的が純投資目的/
23 flag = false
24 end
25
26 text << line2.chomp if flag == true
27 end


Dir.globなどを使えば良いと思うのですが、具体的にはどのように記述すればよいのでしょうか?
ご教授の程お願い致します。

こんばんは。
最近Rubyでファイルのスクローリングをしているのですが、
以下のようなスクリプトを全てのファイルに適用したいと考えています。

1 fpath = '/home/edinet/E30479/S1002D1W/index.html'
2
3 text = ""
4
5
6 File.open(fpath).each do |f|
7 f.each_line do |line|
8
9 line.gsub!(/前事業年度特定投資株式/,"前事業年度")
10 line.gsub!(/当事業年度特定投資株式/,"当事業年度")
11
12 end
13 end...続きを読む

Aベストアンサー

あと、このプログラム、なんか変ですよ?

File.open(fpath).each

ここのeachって変ですよね。

f.each_line do |line|
line.gsub!(/前事業年度特定投資株式/,"前事業年度")

ここでの 変数lineに入っているのは、「ファイルから読み込んだ文字列」です。
ファイルの内容をメモリ上にコピーしたものです。
これを変更しても、元のファイルは変更されません。

また、一行読み込む度に次の行の内容になるので、gsubした結果はどこにも残りません。

Q#include int main(void) { int n1, n2; pu

#include <stdio.h>


  int main(void)

{

    int n1, n2;

    

    puts("2つの整数を入力してください");

    printf("整数1:27"); scanf("%d",&n1);

    printf("整数2:35"); scanf("%d",&n2);

    

    printf("それらの和は%dです\n",n1+n2);  

    return(0);

}

これで実行して
整数 1:27
整数 2:35
それらの和は62です
と表示したいですけど 整数1:27しか表示されませんどうすればいいですか?

Aベストアンサー

それって

整数 1:
 と画面に表示されて、入力待ちになるので
27[エンターキー]
 と入力すると、画面上は
整数 1:27
 となって、続けて
整数 2:
 と表示されて、入力待ちになるので
35[エンターキー]
 と入力すると、画面上は
整数 2:35
 と表示されて、続けて
それらの和は62です
 と表示されて終了する。

というものの実行結果が、画面上では

整数 1:27
整数 2:35
それらの和は62です

と見える、ってことでしょう。


> 整数1:27しか表示されませんどうすればいいですか?

scanfで入力を待っているのに、何も入力しないから、先に進まないだけです。

QRubyにおける、XPathの関数「text()="x"」への変数の使

Rubyにおける、XPathの関数「text()="x"」への変数の使用方法

お世話になります。

RubyにてXPathの関数「text()="x"」"x"の部分に変数を使用したいと思い、コードを作成しています。
text() 関数のところで困っています。

例えば
<?xml version="1.0" encoding="UTF-16"?>
<NameRoot>
<Text>
<Name>あああああ</Name>
<No>001</No>
</Text>
<Text>
<Name>いいいいい</Name>
<No>002</No>
</Text>
<Text>
<Name>ううううう</Name>
<No>003</No>
</Text>
</NameRoot>

の内容のファイルを読み込み、その中から該当するNoに相当するNameを取得しようと
しています。
で、書いたのが下記のような内容なのですが、gettestクラスのgetNameメソッドにて
コメントアウトしてある行であれば、決め打ちでNo="001"の物を取ってこれるのですが、
ここに引数として渡されたローカル変数の、idを使用しようとするとnode変数にNilClass
が返ってきて取得できません。
文字列リテラルを色々調べてみたのですが、どうも上手く行かず困っています。
他愛も無い質問かもしれませんが、大変困っています。
どなたか知恵をお貸しくださいますようお願い致します。

class gettest
def getName(id)
#↓これがきちんと動きません
node = REXML::XPath.first(@masterdata, '//NameRoot/Text/No[text()="#{id}")]')

#↓こちらは当然ながら動きます
# node = REXML::XPath.first(@masterdata, '//NameRoot/Text/No[text()="001"]')

path = (node.xpath + "/../Name")
@name = @masterdata.elements[path].text()
end
end

class main
def edit
@mastername = ""
@mastername = @master.getName("001")
print @mastername
end
end

Rubyにおける、XPathの関数「text()="x"」への変数の使用方法

お世話になります。

RubyにてXPathの関数「text()="x"」"x"の部分に変数を使用したいと思い、コードを作成しています。
text() 関数のところで困っています。

例えば
<?xml version="1.0" encoding="UTF-16"?>
<NameRoot>
<Text>
<Name>あああああ</Name>
<No>001</No>
</Text>
<Text>
<Name>いいいいい</Name>
<No>002</No>
</Text>
<Text>
<Name>ううううう</Name>
<No>003</No>
</Text>
</NameRoot>

の内容のファイルを読み込み、その中から該...続きを読む

Aベストアンサー

#{式} の展開は、" " の中だけです。' ' の中では効きません。

node = REXML::XPath.first(@masterdata, "//NameRoot/Text/No[text()='#{id}')]")


人気Q&Aランキング

おすすめ情報