AでなくBでもない(否定論理和)のマクロNo.32942
柳絮 さん 14/02/15 12:34
 
否定論理和というのでしょうか、AでなくBでもないをマクロコマンドでどう表現する
のかお教えください。



Aでないというのは実際には
特定文字(英字大文字、数字、和文など)以外です。

Bでないというのは実際には
☆と★とで囲まれた部分以外です。

実現したいのは、英和混在テキストから英文小文字を削除して英字大文字、数字、和
文などを残すことです。しかしそれと同時に☆と★とで囲まれた部分は無条件に残し
ておくという別の要求があります。つまり☆と★とで囲まれた部分には英字の小文字
があっても削除されないようにしたいのです。



Aでない単体、またはBでない単体はそれぞれ動くのですが、両方を合わせるとうまく
動きません。否定論理和であろうと考えパイプでつないで見ましたが、期待している
動きにならないのです。

Aでないは実際には
eplaceallfast "[^A-Z\\(\\)\\.\\+\\-\\=%0-9 -K\\n]" , "" , regular, casesen
se, inselect, nohilight;

Bでないは実際には
replaceallfast "([^☆★\\n]+(?=☆))|([^☆★\\n]+$)" , "" , regular, casesens
e, inselect, nohilight;

としてあります。

ところがAでなくBでもないを
"([^A-Z\\(\\)\\.\\+\\-\\=%0-9 -K\\n])|([^☆★\\n]+(?=☆))|([^☆★\\n]+$)"
とすると動かないのです。

お知恵を拝借できれば幸いですので、どうぞよろしくお願いします。
柳絮

[ ]
RE:32942 AでなくBでもない(否定論理和)No.32943
いいじま さん 14/02/15 22:21
 
秀丸ユーザーのいいじまと申します。

> 否定論理和というのでしょうか、AでなくBでもないを
> マクロコマンドでどう表現するのかお教えください。

結論から申し上げますと、正規表現にはもともと、そういう
記法はありません。
前方不一致指定は(たぶん規格はあるのだと思いますが)
秀丸独自のもので非対応エンジンが多いですし、中間不一致かつ
外部一致指定というものは私の知る限りではありません。

> 実現したいのは、英和混在テキストから英文小文字を削除して
> 英字大文字、数字、和文などを残すことです。しかしそれと
> 同時に☆と★とで囲まれた部分は無条件に残しておくという
> 別の要求があります。つまり☆と★とで囲まれた部分には英字の
> 小文字があっても削除されないようにしたいのです。

とすれば、先頭から1文字ずつ見ていくのが順当だと思います。

#STARTMARK = '☆';
#ENDMARK   = '★';

movetolineno 1,1;

#isInsideMark = 0;
while (code >= 0)
{
 if ((!#isInsideMark) && 'a'<=code && code<='z')
 {
  delete;
  continue;
 }

 if (code == #STARTMARK)
 {
  if (#isInsideMark)
  {
   message char(#STARTMARK) + "の中に" + char(#STARTMARK)
    + "があります。無視します。";
   }

  #isInsideMark = 1;
 }
 else if (code == #ENDMARK)
 {
  if (!#isInsideMark)
  {
   message char(#ENDMARK) + "の外に" + char(#ENDMARK)
    + "があります。無視します。";
  }

  #isInsideMark = 0;
 }

 right;
}

[ ]
RE:32942 AでなくBでもない(否定論理和)No.32944
アルビレオ さん 14/02/15 23:22
 
ユーザーのアルビレオです。

いいじまさんも言われているように、ひとつの正規表現パターンとして記述する
のは無理ですね。

挙げられている条件では不明確な点があるので、処理が簡単になるように都合の
いい解釈をします。
・☆と★の囲みは行をまたぐ場合があるのか→またがない
・☆と★は必ず対になっていて、入れ子になったり、☆だけや★だけが単独で出
てくることはないのか→必ず対になる、単独では出てこない
・inselect(選択範囲のみ置換)は必要?→不要、必ずテキスト全体を置換

上のような条件だと「☆と★が出てこない行全体」または「行頭から☆まで」ま
たは「★から行末まで」の英小文字だけを削除するだけでいいことになります。


no_star://☆★なし
gofiletop;
replaceallfast "^([^☆★]*)[a-z]+([^☆★]*)$", "\\1\\2", casesence,
regular;
if(result>0) goto no_star;

before_star://行頭から☆まで
gofiltop;
replaceallfast "^([^☆★]*)[a-z]+([^☆★]*)☆", "\\1\\2☆", casesence,
regular;
if(result>0) goto before_star;

after_star://★から行末まで
gofiletop;
replaceallfast "★([^☆★]*)[a-z]+([^☆★]*)$", "★\\1\\2", casesence,
regular;
if(result>0) goto after_star;


すべての小文字を削除するまで何度もループさせる必要がありますが、一文字ず
つチェックするやり方よりはかなり高速なはずです。

[ ]
RE:32942 AでなくBでもない(否定論理和)No.32946
柳絮 さん 14/02/16 08:54
 
飯島さん、アルビレオさんコメントを有難う御座いました。

否定論理和というものがないとわかっただけでも収穫です。稔りのない方法を探し続
ける必要がなくなったと言うことで助かりました。そうなれば飯島さんのおっしゃる
ように先頭から順番に見ていくしかないのでしょうね。

私は抽象的に考えていたのですけれども、お二人は具体的に前から順番に見ていくと
言う着実な方法をお示しくださり勉強になりました。特に行の中で☆★に注目すると
いうのは、違う角度からのものの見方を教えていただいたように思います。

条件としてはアルビレオさんのおっしゃるもので結構です。
・☆と★の囲みは行をまたがない
・☆と★は必ず対になり、入れ子や単独では出現しない
・テキスト全体を置換し選択範囲のみの置換は不要

今アルビレオさんが書いてくださったものを動かしてみましたがうまくいっています。
ただし一つの行に☆★で囲まれたものが2つ以上出てくる場合がありますので、★か
ら☆の間をチェックするロジックが1つ必要になるかと思います。もしわかればそれ
もご教示ください。

お二人にお時間をいただいたことに感謝しています。

柳絮

[ ]
RE:32946 AでなくBでもない(否定論理和)No.32947
山紫水明 さん 14/02/16 09:22
 
 柳絮さん,

>・☆と★の囲みは行をまたがない
>・☆と★は必ず対になり、入れ子や単独では出現しない

という限定条件があるなら,

replaceallfast "(?<!☆[^★]*)[a-z]+(?![^☆]*★)", "", regular, casesense,
inselect, nohilight;

でいけませんか。十分に検証したわけではありませんが。

                          山紫水明
                          SANSHISUIMEI

[ ]
RE:32947 AでなくBでもない(否定論理和)No.32948
柳絮 さん 14/02/16 14:50
 
山紫水明さん、コメントを有難う御座いました。お書きになっているコマンドで動き
ました。

まだ後方不一致前方不一致などのコマンドをよく理解していない状況で、お作りの
ホームページも参照させてもらいながら勉強して、いずれは皆さんにフィードバック
できるようになりたいと思います。

まずは御礼まで。

柳絮

[ ]