14

回そうとする

a: 1, 2, 3
a: a, b, v
b: 5, 6, 7
b: 10, 1543, 1345
b: e, fe, sdf
cd: asdf, asdfas dfasdfa,asdfasdfa,afdsfa sdf
e1: asdfas, dafasd, adsf, asdfasd
e1: 1, 3, 2
e1: 9, 8, 7, 6

の中へ

a: 1, 2, 3
   a, b, v
b: 5, 6, 7
   10, 1543, 1345
   e, fe, sdf
cd: asdf, asdfas dfasdfa,asdfasdfa,afdsfa sdf
e1: asdfas, dafasd, adsf, asdfasd
    1, 3, 2
    9, 8, 7, 6

したがって、行はソートされます。連続する行が、区切り文字 (ここではコロン (およびそれに続く空白)) を含む / までの同じ文字シーケンスで始まる場合、最初のインスタンスのみが保持され、残りのすべての行も同様に保持されます。同一の文字シーケンスで始まる最大で約 12 行 (半行) の行が存在する可能性があります。入力は約 4,500 行を保持します…</p>

TextWrangler で試してみました。

検索パターン

^([[:alnum:]]+): (.+)\r((\1:) (.+)\r)*

正しく一致し、置換もありません

\1:\t\2\r\t\3\r

または

\1:\t\2\r\t\4\r

探しているものに近づくことができます。

検索パターン

^(.+): (.+)\r((?<=\1:) (.+)\r)*

後読みが固定長でないため拒否されます。- 確かではありませんが、とにかく正しい方向に進んでいます。

テキストファイル内の同じ項目で始まる行をマージする方法を見て 、エレガントな(たとえば、1つの検索パターン、1つの置換、1回実行)ソリューションがあるかどうか疑問に思います。

一方で、ネットを検索するのに適切な質問を思いつくことができないかもしれません. あなたがよく知っているなら、私を正しい方向に向けてください.

残りの行を整列させておくことは、もちろんおまけです…</p>

お時間をいただきありがとうございます。

4

6 に答える 6

4

選手交代の問題点は、試合数が不確実なことだ。その数をたとえば 12 に制限する場合、次のような正規表現を使用できます。

^([^:]+): ([^\n]+[\n]*)(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?(\1: ([^\n]+[\n]*))?

この置き換えで:

\n\1:\t\2\t\4\t\6\t\8\t\10\t\12\t\14\t\16\t\18\t\20\t\22\t\24

説明:基本的に2つのサブ正規表現のみが含まれています

  • ^([^:]+): ([^\n]+[\n]*)= グループの最初の行に一致

  • (\1: ([^\n]+[\n]*))?= 同じグループに属する、連続する行でのオプションの一致。すべての行に一致するように、この正規表現を必要なだけコピーする必要があります (つまり、この場合は 12x)。( ?= オプションの) 一致は、すべての置換に対して十分な一致がない場合でもエラーになりません。

  • 置換の\n先頭にある は、フォーマットの問題に必要です

  • 結果にはいくつかの空の行が含まれますが、解決できると確信しています... ;-)

デモ1

ただし、私は特大の正規表現のファンではないため、潜在的な一致の数が多い場合は、次のようなソリューションをお勧めします。

デモ 2

于 2015-08-03T02:17:45.193 に答える
1

Bare Bones Software Inc. の TextWrangler でサンプルを試してみたところ、連続するn行に制限された 2 パス ソリューションを思いつきました。これは、プレフィックスの長さを魔法のように一致させる代わりにタブを使用します。また、ファイルの最後の行は空行にする必要があることに注意して, 6ください(例の後に改行を追加してください)

私たちの目的のために、n = 4の場所を示します。

Find: ^([[:alnum:]]+\:)(.+\r)(?:\1(.+\r))?\1(.+)\r
Replace: \1\2\t\3\t\4\t\5\r

a inを複製し、 in beforeを追加することで、任意のnに 1 を追加できます。*n* は、その前の最後の数値の後の増分です。(?:\1(.+\r))?Find\t\n\rReplace\r

すべてをこれに置き換えると、次のようにフォローアップできます。

Find: ^\t+
Replace: \t

ほとんどの場合、必要な結果が得られます。

于 2015-08-04T07:20:10.120 に答える
1

以下の awk ワンライナーは、あなたが望むことを行います

awk -F: 'NR==1 {print $0} NR != 1 {if ($1 != prev) print $0; else {for (i=0; i<=length($1); ++i) printf " "; print $2;}} {prev=$1}' < input_file.txt

(原文をinput_file.txtに入れる)

もっと良いコードを書くことは可能だと思いますが、もう寝る時間です)

于 2015-08-02T03:34:06.417 に答える
0

したがって、最初のインスタンス以外のすべてのインスタンスを置き換えたいので、それらを置き換えることができるように、最初のもの以外のすべてに一致する正規表現が必要だと思います。ご存じのとおり、正規表現は元の文字列を変更または変更することはできず、特定の一致のみを返します。これは、変更する文字列の一部を指定するために使用できます。

私が思いついた最高の正規表現は/(\b[a-zA-Z0-9]+: )[^\n]+(?:\n|$)(?!\1)/g.

これにより、すべての一意のインスタンスがキャプチャされxx:、最後のインスタンスと一致します。これに関する唯一の問題は、それが唯一のインスタンスであっても、最後のインスタンスと一致することです。

私の結論は、正規表現でこれをすべて行うことができるとは思わないということです。後読みと後方参照をサポートするオンライン正規表現デバッガーを誰かが見つけた場合は、私に知らせてください。動作する式を記述できるかどうかを確認します。後方参照と後読みを受け入れる正規表現デバッガーを個人的に見つけることができませんでした。私の例では、代わりに先読みを使用して、先にインスタンスがあるかどうかをチェックし、そうであれば現在の一致を無視します (したがって、最後のインスタンスのみを選択します)。

これを自動化して機能させる方法を本当に見つけたい場合は、 を使用/(\b[a-zA-Z0-9]+: )/gして のすべてのインスタンスを照合しxx:、それらをすべて配列に格納します。重複がある場合は、その特定の正規表現に対して元の正規表現を実行して、重複はもうありません。繰り返しますが、それを使用してすべての一意のインスタンスを保存し、それを何らかの方法で利用できる場合があります。

これが問題の解決に役立つことを願っています。そうでない場合はお詫び申し上げます。

于 2015-08-02T03:13:56.977 に答える