2012-04-14 5 views
-1

は、私は次のように苦労していた場合に複数行を交換する正規表現。つ以上の

私は特定の形式でのMoodle(オンライン質問サイト)にインポートする必要がある質問と答えとワードファイルがあります。すべてが正解のために黒で受け入れられます、これらは緑です。出力は

:Question example 

:Question example 

{ 

~ Wrong 

~ Wrong 

~ Wrong 

= Right 

} 

私は言葉でファイルを開くには、すべての赤の段落記号を置き換えるになるべき

1. Question example 

a. Wrong 

b. Wrong 

C. Wrong 

D. Right 

(私はグループで置き換えることができません)*で:スタート形式は以下の通りです。その後、.docxファイルをテキストにエクスポートします。 私のLinuxコンピュータで開き、次の正規表現を投げてください。

sed -i -e 's/^\r/\n/g' tmp #OS X white line replacement      
sed -i -e 's/\r//g' tmp #remove white lines       
sed -i -e 's:^[a-z]\.:~:' tmp #Replace Leading question letters with tilde                        
sed -i -e 's/\(^[0-9]*\.\ \)\(.*\)/}\n::\2\n::\2\n{/' tmp #regenerate tittle      
sed -i -n '${p;q};N;/\n\*/{s/"\?\n//p;b};P;D' tmp #next line starts with * append to front of current                
sed -i -e 's:^~\(.*\)\(\*.*\)$:=\1:' tmp #move * from back to = to front 
sed -i -e 's:^\*:=:' tmp #replace any remaining * with =   
sed '/^$/d' tmp #delete any remaining white lines 

これは素晴らしいことではありませんが、問題は手作りであり、エラーが多いので、手でこれを歩かなければなりません。難しいのは、複数の正解があるときです。出力は次のようになります。

:Question example 

:Question example 

{ 

~%-100% Wrong 

~%-100% Wrong 

~%50% Right 

~%50% Right 

} 

理想的には私は=の量は間{と〜%〜50%に置き換え歌っカウントのsedやperlの正規表現を持っています。そして%〜100%のすべての〜が歌います。 3つの正解についてもこのコードを持つことができ、すべての正解が〜%33%になります。

これは実行可能ですか?私は1000以上の質問があり、それは確かにこれを自動化するのに役立ちます。 sedによる複数行の置換は2行でややこしいので、4行以上の行にはperlが必要でしょうか?私はPerlでの経験がありません。

誰かがこの1で私を助けてもらえますか?私の悪い英語を許してください。私は母国語ではない話し手です。

+0

sed hold space操作を参照してください。それは難しいようですが、私はそれらを使用して可能だと思います。 –

+0

WindowsとLinuxの異なる改行について何をしていますか?また、引用符のように、あなたが「訂正」する文字のすべてについてはどうでしょうか? – stark

+0

実際の例をいくつか示しておけば、それは多くの助けになります。実際のテキストとプレースホルダーがあなたの例から分かりにくいです。ソースファイルに 'Wrong'と' Right'と表示されますか?もしそうなら、どの答えが正しいのか、そしてどちらが間違っているのかを教える方法は?そうでない場合、出力ファイルにはどのような点がありますか? – Borodin

答えて

1
my $file = do { local $/; <> }; 
my @questions = split /(?<=.)(?=[0-9]+\.)/s, $file; 
for (@questions) { 
    my @lines = split /^/m; 

    my $title = shift(@lines); 
    $title =~ s/^\S+\s*/:/; 

    my $num_right; 
    my $num_wrong; 
    for (@lines) { 
     if (/Right/) { ++$num_right; } 
     elsif (/Wrong/) { ++$num_wrong; } 
    } 

    my $num_answers = $num_right + $num_wrong; 

    my $right_pct = sprintf('%.0f', $num_right/$num_answers*100); 
    my $right_prefix = $num_right == 1 ? "=" : "~%$right_pct%"; 
    my $wrong_prefix = $num_right == 1 ? "~" : "~%-100%"; 

    for (@lines) { 
     if (/Right/) { s/^\S+/$right_prefix/; } 
     elsif (/Wrong/) { s/^\S+/$wrong_prefix/; } 
    } 

    print(
     $title, 
     "\n", 
     $title, 
     "\n{\n", 
     @lines, 
     "\n}\n", 
    ); 
} 

適切な何かを/Right//Wrong/を交換してください。

+0

編集後、 'print'文の最初の改行の後ろに'、 'がありません。条件付き演算子は接頭辞を決定する際に '$ num_wrong'の代わりに' $ num_right'を使うべきです。 – Borodin

+0

固定、ありがとう.. – ikegami

1

以下のプログラムは、自分が必要としているところで私の最高の推測に基づいて動作します。これは、すべての情報を配列に読み込んだ後、フォーマットすることによって機能します。

データはそのままソースに組み込まれ、ファイルハンドルDATAから読み取られます。ループをwhile (<>) { ... }に変更すると、コマンドラインでデータファイルを指定できます。

私の推測が間違っている場合は、私を修正する必要があります。これはあなたのために働くかもしれない

use strict; 
use warnings; 

my @questions; 

while (<DATA>) { 
    next unless /\S/; 
    s/\s+$//; 
    if (/^\d+\.\s*(.+)/) { 
    push @questions, [$1]; 
    } 
    elsif (/^[A-Za-z]\.\s*(.+)/i) { 
    push @{$questions[-1]}, $1; 
    } 
} 

for my $question (@questions) { 

    my ($text, @answers) = @$question; 

    print "::$text\n" for 1, 2; 

    my $correct = grep /right/i, @answers; 
    my $percent = int(100/$correct); 

    print "{\n"; 

    if ($correct == 1) { 
    printf "%s %s\n", /right/i ? '=' : '~', $_ for @answers; 
    } 
    else { 
    my $percent = int(100/$correct); 
    printf "~%%%d%%~ %s\n", /right/i ? $percent : -100, $_ for @answers; 
    } 

    print "}\n"; 
} 

__DATA__ 
1. Question one 

a. Wrong 

b. Wrong 

c. Right 

d. Wrong 

2. Question two 

a. Right 

b. Wrong 

c. Right 

d. Wrong 

3. Question three 

a. Right 

b. Right 

c. Wrong 

d. Right 

出力

::Question one 
::Question one 
{ 
~ Wrong 
~ Wrong 
= Right 
~ Wrong 
} 
::Question two 
::Question two 
{ 
~%50%~ Right 
~%-100%~ Wrong 
~%50%~ Right 
~%-100%~ Wrong 
} 
::Question three 
::Question three 
{ 
~%33%~ Right 
~%33%~ Right 
~%-100%~ Wrong 
~%33%~ Right 
} 
1

:次に

cat <<\! >file.sed 
> # On encountering a digit in the first character position 
> /^[0-9]/{ 
> # Create a label to cater for last line processing 
> :end 
> # Swap to hold space 
> x 
> # Check hold space for contents. 
> # If none delete it and begin a new cycle 
> # This is to cater for the first question line 
> /./!d 
> # Remove any carriage returns 
> s/\r//g 
> # Remove any blank lines 
> s/\n\n*/\n/g 
> # Double the question line, replacing the question number by a ':' 
> # Also append a { followed by a newline 
> s/^[0-9]*\.\([^\n]*\n\)/:\1:\1{\n/ 
> # Coalesce lines beginning with a * and remove optional preceeding " 
> s/"\?\n\*/*/g 
> # Replace the wrong answers a,b,c... with ~%-100% 
> s/\n[a-zA-z]*\. \(Wrong\)/\n~%-100% \1/g 
> # Replace the right answers a,B,c... with ~%100% 
> s/\n[a-zA-Z]*\. \(Right\)/\n~%100% \1/g 
> # Assuming no more than 4 answers: 
> # Replace 4 correct answers prefix with ~%25% 
> s/\(~%100%\)\(.*\)\1\(.*\)\1\(.*\)\1/~%25%\2~%25%\3~%25%\4~%25%/ 
> # Replace 3 correct answers prefix with ~%33% 
> s/\(~%100%\)\(.*\)\1\(.*\)\1/~%33%\2~%33%\3~%33%/ 
> # Replace 2 correct answers prefix with ~%50% 
> s/\(~%100%\)\(.*\)\1/~%50%\2~%50%/ 
> # Append a newline and a } 
> s/$/\n}/ 
> # Break and so print newly formatted string 
> b 
> } 
> # Append pattern space to hold space 
> H 
> # On last line jump to end label 
> $b end 
> # Delete all lines from pattern space 
> d 
> ! 

実行します。

sed -f file.sed file 
0

あなたの例では、この文書に一致しませんatheon:http://docs.moodle.org/22/en/GIFT。質問のタイトルとquestiosnは二つのコロンない1つのコロンで区切られています。

//Comment line 
::Question title 
:: Question { 
=A correct answer 
~Wrong answer1 
#A response to wrong answer1 
~Wrong answer2 
#A response to wrong answer2 
~Wrong answer3 
#A response to wrong answer3 
~Wrong answer4 
#A response to wrong answer4 
} 

一部の人々は、単純に、あなたの例の代わりに、おっと、実際の仕様を見つけることに基づいて、あなたに答えを与えました。

あなたの質問には、あなたの書式が正しい答えを明らかにしていないため、答えられません。それは言うことです:

1. Question 

a. Is this right? 

b. Or this? 

c. Or this? 

あなたはこれらを元のWord文書で、あなたが情報を保持することで、いくつかの交換を行うことを、色を使用して識別されていると言います。しかし、あなたはこれの例を示していません!おっと...