■ QGREP ■

131 にジャンプ
No. 128投稿者: さと日付: 2003/01/16 01:57:57
題名 : マッチした場所に文字列を出力

「マッチした場所に文字列を出力」を使おうとしているのですが、
うまく「文字列を出力」しない場合があります。

まず、ひとつの単語で検索し、検索した言葉が同じパラグラフで
二ヶ所以上ある場合、
先にあるほうにしか出力されません。

また、「or検索」した場合も、最初にヒットした方しか出力されません。

なにか設定が間違っているのでしょうか?
(それとも、そもそも不可能なことでしょうか)
もし、解決法があれば教えてください。

よろしくお願いします。

No. 129 (128へのコメント)投稿者: CINEPHILE日付: 2003/01/18 16:53:08
題名 : Re:マッチした場所に文字列を出力

>まず、ひとつの単語で検索し、検索した言葉が同じパラグラフで
>二ヶ所以上ある場合、
>先にあるほうにしか出力されません。
>
>また、「or検索」した場合も、最初にヒットした方しか出力されません。

 改行まで一行ずつ(つまりパラグラフ単位で)読み込んで、ヒットしたら次
へ行くという動作になると思うので、現状では無理かもしれません。また、演
算子 or を使う場合は、どれか一つヒットすれば条件を満たすことになるので、
やはりこのようになってしまうような気がします。
 ログを QX で開いているのであれば、文字列が出力されなかった箇所だけ、
正規表現を使って適当に置換するというのはどうでしょうか。

\([^◎]\)QX → \1◎QX

 しかし、これなら最初から文字列を出力せずに、ログを普通に置換しても同
じことですね。

QX → ◎QX

 勝手にやってくれるといいんですが、検索条件があまり複雑でなければ、手
作業でもそれなりにしのげるのでは?

No. 130 (129へのコメント)投稿者: さと日付: 2003/01/22 01:59:26
題名 : Re^2:マッチした場所に文字列を出力

CINEPHILEさん、返信ありがとうございます。

やはり現段階では難しいのでしょうか。

実はログを置換たり検索したりいろいろためしました。
(ちなみに、ログというのは検索結果が出力されてくるファイルの
ことでいいですよね?)

しかし、複雑な検索<例えば、「( A or B or C ) and ( D or E or F )」のような>
をやっているためなにぶん手間がかかります。

また、2行にまたっがった単語の場合、QXでは検索や置換はできないのではないでしょうか。

100以上のヒットがあるものを何十回も繰り返す必要があり、
本当に疲れてしまいます。

何かいい方法ってないんでしょうかねえ。

No. 131 (130へのコメント)投稿者: CINEPHILE日付: 2003/01/22 21:12:10
題名 : Re^3:マッチした場所に文字列を出力

>しかし、複雑な検索<例えば、「( A or B or C ) and ( D or E or F )」のような>
>をやっているためなにぶん手間がかかります。

 QGREP.INI から最新の履歴を取得して、すべての文字列に関して一括置換を
実行するという手順で半自動化することは、理屈の上では可能だとは思います
が、これだけ条件が複雑だと、まず文字列をすべて取り出すのが大変かもしれ
ません。
 QGREP が取り出せるのだから、マクロで取り出せないはずはありませんが、
文字列には当然正規表現が含まれる可能性もあるので、あれこれ考えると、や
はりかなりハードルが高そうです。

# ちょっと長くなるので、いったん切ります。

No. 132 (130へのコメント)投稿者: CINEPHILE日付: 2003/01/22 21:13:35
題名 : Re^3:マッチした場所に文字列を出力

>また、2行にまたっがった単語の場合、QXでは検索や置換はできないのではないでしょうか。

 QGREP はおそらく行末の改行を読み込んでいないので、2行を連結した時に、
あたかも途中の改行が無いかのように検索することができるんだと思います。
普通に検索すればこの改行が挟まれるので、これを無視して検索するのは案外
やっかいです。
 とりあえず試作品程度ですが、カーソル位置以降を検索して、ヒットした位
置の直前に指定した文字列を挿入します。正規表現は使用できません。大文字
・小文字は区別されます。一度のアンドゥでもとに戻せるので心配ないとは思
いますが、あらかじめ安全なファイルで試してみてください。
 通常の検索機能を使用していないので、巨大なファイルで実行すると処理に
時間がかかるかもしれませんが、QGREP の出力程度であれば何とか我慢できる
かと思います。いろいろ制限が多いので、使いにくいかもしれませんが。



const c$ = "◎"  '挿入する文字列

proc main
	dim w$,s$,length,pos,ret,i
	if @hwnd = 0 then exit proc
	dialog "検索語入力",150,100,150,12,0,"MS ゴシック",-14
	control "",100,"EDIT",ES_AUTOHSCROLL|WS_TABSTOP,0,0,150,12
	control "",IDOK,"BUTTON",0,0,0,0,0
	control "",IDCANCEL,"BUTTON",0,0,0,0,0
	do while 1
		ret = dialog(1)
		if ret = IDCANCEL then exit proc
		if ret = IDOK then
			if dlgtext$(100) <> "" then
				w$ = dlgtext$(100)
				call dialog(0)
				exit do
			end if
		end if
	loop
	@Redraw = 0:@UndoBlock = 1
	do while @Line < @LastLine
		pos = 1:i = 0
		s$ = @TextCr$(@Line)
		length = lenb(s$)
		@MoveNextLineCr
		s$ = s$+@TextCr$(@Line)
		@MovePrevLineCr
		do while instrb(pos,s$,w$) > 0
			pos = instrb(pos,s$,w$)
			if pos > length then exit do
			@BytePosCr = pos+lenb(c$)*i++
			@Insert c$
			pos = pos+1
		loop
		@MoveNextLineCr
	loop
	@Redraw = 1:@UndoBlock = 0
end proc

No. 133 (130へのコメント)投稿者: CINEPHILE日付: 2003/01/23 18:36:07
題名 : Re^3:マッチした場所に文字列を出力

 一応こんなの作ってみましたが、どうでしょうか?



'QGREPの検索語の直前に文字列を挿入

#comment
・QGREP.INIから自動的に最新の履歴を取得するので、検索終了後、検索結果
  をQXで開いた状態で実行する。
・2行連結には対応していない。
#comment

const c$ = "◎"  '挿入する文字列

proc main
	dim ini$,case,regexp
	dim s$,ss$,item$[10],i,case_sensitive,line,byte,top
	if @hwnd = 0 then exit proc
	'QGREPをQXと別のディレクトリにインストールしている場合は
	'QGREP.INIをフルパスで指定する。(例)ini$ = "C:\QGREP\QGREP.INI"
	ini$ = @@QxDirectory$+"\QGREP.INI"
	if dir$(ini$) = "" then
		call msgbox("QGREP.INIがありません。",MB_ICONINFORMATION)
		exit proc
	end if
	s$ = getprofile$("search","string0",ini$)  '最新の検索履歴を取得
	if s$ = "" then
		call msgbox("履歴がありません。",MB_ICONINFORMATION)
		exit proc
	end if
	case = val(getprofile$("search","Case",ini$))
	regexp = val(getprofile$("search","Regular",ini$))
	i = 1
	do while s$ <> ""
		if instr(s$," ") = 0 then
			ss$ = s$
			s$ = ""
		else
			ss$ = left$(s$,instr(s$," ")-1)
			s$ = mid$(s$,instr(s$," ")+1)
		end if
		if ss$ <> "and" and ss$ <> "or" and ss$ <> "not" \
				and ss$ <> "(" and ss$ <> ")" then
			item$[i++] = ss$
		end if
	loop
	@@ReplaceStringMulti
	case_sensitive = @@FindCaseSensitive
	if case = 0 then
		@@FindCaseSensitive = 1
	else
		@@FindCaseSensitive = 0
	end if
	i = 1
	if regexp = 1 then
		@@FindRegExp = 1:@@FindRegExp = -2
		do while item$[i] <> ""
			@@ReplaceStringMulti "\("+item$[i]+"\)",c$+"\1"
			i++
		loop
	else
		do while item$[i] <> ""
			@@ReplaceStringMulti item$[i],c$+item$[i]
			i++
		loop
	end if
	@Redraw = 0:@UndoBlock = 1
	line = @Line:byte = @BytePos:top = @TopLine
	@MoveFileTop  'ファイルの先頭から実行
	@ReplaceStringMultiExec 1
	@Line = line:@BytePos = byte:@TopLine = top
	@Redraw = 1:@UndoBlock = 0
	@@FindCaseSensitive = case_sensitive
end proc

No. 134 (133へのコメント)投稿者: さと日付: 2003/01/27 02:12:48
題名 : Re^4:マッチした場所に文字列を出力

CINEPHILEさん、ありがとうございました。

マクロのことはあまり分からないのですがトライしてみます。


ヘッダのみ表示
順番に表示(No. 131 から)


メールアドレスを表示するにはURLの後ろに &m=6947ef7c をつけてください。
フォーラム一覧

http://www2k.biglobe.ne.jp/~araken/
http://0ban.com/araken/