某巨大掲示板ではレスが付かなかったので移動してきました。
Adobe illustrator CS1でjavascriptを使って文字列の検索置換を行った時に
変更部分を目視で確認したいので置換した文字部分のみ色を換えたいのです。(添付の画像の様な状態)
正規表現を使って文字列置換するのは簡単なんですが、色を変えようとするとうまい方法が思いつきません。
100以上のパターンを検索置換しないといけません。
お知恵をお貸しください。
[15063] AM66 (2012/12/26 Wed 09:50)
検索したトコの
CharacterAttributes.FillColor
に任意の色指定すれば良いと思うです。
[15064] 流星光輝 (2012/12/26 Wed 10:37) web
すみません。色の指定方法がわからないという話ではありません。
[15065] AM66 (2012/12/26 Wed 10:47)
> すみません。色の指定方法がわからないという話ではありません。
そうですか。ご存知でしたか。
>正規表現を使って文字列置換するのは簡単なんですが、色を変えようとするとうまい方法が思いつきません。
色の変更点を示せば、後はロジックだけだと思うのですけれど、
いま、詰まってるコードかいてもらえますか?
[15066] 流星光輝 (2012/12/26 Wed 11:42) web
ちょっとソースは晒せないのですが、
例えば
「今日は良い天気だ。」の[今日]を置換・色換えすると「[明日]は良い天気だ」になりますが、([]は色換えした部分です。)
そこから更に
「[明日]は良い天気だ」の[良い]を置換・色換えしようと思うと普通に処理すれば「明日は[悪い]天気だ」にはできますが、
「[明日]は[悪い]天気だ」にするのが難しいという話です。
この場合のように検索・置換パターンが2つぐらいならそこまで処理も遅くならないと思いますが、
検索・置換ワードが100パターン以上存在するので普通に処理していくと大変な時間がかかってしまうのです。
[15068] AM66 (2012/12/26 Wed 12:53)
えー 流れ(意味)が、さっぱり分かりません。
速い、遅いっていう件は、最初に提示されていませんね。
・正規表現で置換するんじゃないの?
・正規表現置換はreplaceでやってるんですよね?
・その時、置換した部分を捕まえられないから単純に検索してる?
・文字列の単純一致でなら色変更は出来てるけど、遅いっていうの?
#今後のために
聞きたいことを最初にまとめてスレ立てましょう。
どこまでやってみたのかは最初に書きましょう。
ソースが晒せないのは最初に書きましょう。
以上。
[15069] 流星光輝 (2012/12/26 Wed 14:22) web
確かに分かり辛いので再度書きます。
自分が当初考えていたロジックは画像の様な結果を出したい時に、
'良い'を置換して、置換後のキャラクターポジションを配列に入れておき、
後からそこの部分の色を変更すれば良いと思っていましたが、
今日はいつもより良さげな天気だと思う
chrPos=[8,11]
次に'今日は'を置換した場合に、文字列長も変わるので、当然当初のポジションもずれてきます。
あさってはいつもより良さげな天気だと思う
chrPos=[0,4],[10,13]
となると、検索ワード毎にcharPosと比較して配列の数値を増減させていかなくてはならないので
ちょっと実用的じゃないかと思ったので、質問させていただきました。
(現状、単純な検索置換だけでも文字数によっては結構な時間がかかります。)
他にはとりあえず全て検索置換して、元の文章と比較して、差分を色換するぐらしか思いつきませんでした。
[15070] AM66 (2012/12/26 Wed 15:19)
ということは、
正規表現の置換ではなくて、
文字列の単純な置換+色変更がしたい
ということですよね。
検索のみ
色変更
文字列変更
を繰り返せばいいのでは?
[15071] 流星光輝 (2012/12/26 Wed 15:47) web
いえ、実際にはもっと複雑なパターンを検索しなくてはいけないので
正規表現じゃないと都合が悪いのです。$1値とかも使うので。
検索→色変更→文字列の繰り返しは試されると分かりますが、
textFrame.contentsの内容が入れ替える度に
前の色変更が無効になってしまいますので、
結局どこかで色を換えた位置を記憶しておく必要があるんですよね。
[15072] AM66 (2012/12/26 Wed 15:56)
> 検索→色変更→文字列の繰り返しは試されると分かりますが、
> textFrame.contentsの内容が入れ替える度に
> 前の色変更が無効になってしまいますので、
> 結局どこかで色を換えた位置を記憶しておく必要があるんですよね。
contentsにまるまる入れてたら変更した色が最終的にどうなるかは分からないですよね。
置換時に先に元文字に着色して、その部分だけ入れ替えたいもの($1で拾った文字とか)に差し替えればいいのでは?
あと、気になったのですけども、
リストが100とかおっしゃられてたと思うのですが、
リスト内で置換処理が崩壊しませんよね?(下記のように
元テキスト:あb2_1aあ
検索・置換処理:
s/(b2)_(1a)/$2_$1/
s/(a)_(b)/$2_$1/
置換後テキスト:あ1b_a2あ
みたいにならないかという意味です。
[15081] 流星光輝 (2012/12/27 Thu 11:19) web
> 置換時に先に元文字に着色して、その部分だけ入れ替えたいもの($1で拾った文字とか)に差し替えればいいのでは?
このやり方がわからないのですが、textFrame.contentsを部分的に入れ替えできるのですか?
この方法ができれば実現しそうですが。
> リスト内で置換処理が崩壊しませんよね?(下記のように
置換処理の詳細もまだ実験しかやっていないのですが、多分問題無いと思っています。
[15086] AM66 (2012/12/27 Thu 13:52)
characters[i].contentsで変更できました。
ちょっとこの線でつくってみます。
[15087] AM66 (2012/12/27 Thu 14:05)
ありがとうございました。
とりあえず予定通りの動作をするものはできたようです。
ただ、現状は
検索をかける→見つかった文字列の頭一文字の色を変更→
文字列の頭一文字以外を削除→文字列の頭一文字を置換文字列に置き換え
という方法でやっているのですが、「文字列の頭一文字以外を削除」で
ムダな時間を食ってしまっています。
もうちょっとスマートなやり方がありましたら教えてください。
[15090] AM66 (2012/12/27 Thu 15:40)
illustratorのスクリプトはよくわかっていない上に、CS2以降しかないので無理かもしれませんが、replace()の第二パラメータに関数を使ってうまくできないものでしょうか?
InDesign CS2のJSですが、
http://www.openspc2.org/book/InDesignCS2/normal/RegExp/003/index.html
このrepFunc(chr,ptr,allStr)の中の引数ptrがポジションらしい(illustrator CS2ではポジションを返しました)ので、chrを使って連想配列で置換文字列を戻しつつ、大域変数のテーブルに置換した(ポジション,置換文字数)を記録しつつ、ポジションがずれる場合の処理もrepFuncの中で処理してしまう、というのは無理でしょうか。
[15073] ななし (2012/12/26 Wed 16:13)
下記の様に書き直せばAI CS1で動きましたが、
この場合のrepFunc(chr,ptr,allStr)の引数の部分って何処から受け取ってるんでしょう?
自分の知識ではよくわかりません。
myTextFrames = app.activeDocument.textFrames;
for (j=0; j<myTextFrames.length; j++)
{
txt = myTextFrames[j].contents;
result = txt.replace(/[A-Z]/g, repFunc);
myTextFrames[j].contents = result;
}
function repFunc(chr,ptr,allStr)
{
var hankaku = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var zenkaku = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var n = zenkaku.indexOf(chr);
return hankaku.charAt(n);
}
[15075] AM66 (2012/12/26 Wed 17:40)
> この場合のrepFunc(chr,ptr,allStr)の引数の部分って何処から受け取ってるんでしょう?
> 自分の知識ではよくわかりません。
自分もよく分かっていないのですが、Stringクラスのreplaceメソッドから渡されているということになるのではないでしょうか?
自宅からなのでちょっと調べられないですけれど、replace()以外でもこういう感じの関数を使えるものがあったと思います。
[15076] ななし (2012/12/26 Wed 19:31)
今回こちらの手法はうまく活かせていませんが、勉強になりました。
ありがとうございました。
[15091] AM66 (2012/12/27 Thu 15:42)
>この場合のrepFunc(chr,ptr,allStr)の引数の部分って何処から受け取ってるんでしょう?
ググって、それらしいものを見つけましたが、1/10も理解できないのですが……
https://developer.mozilla.org/ja/docs/JavaScript/Reference/Global_Objects/String/replace
それと、Arrayクラス(インスタンスの方が正しいのでしょうか?)のsortメソッドでも引数に関数が使えました。
>今回こちらの手法はうまく活かせていませんが、勉強になりました。
>ありがとうございました。
いえいえ、どういたしまして。こちらこそ、勉強ができましてありがとうございます。
[15092] ななし (2012/12/27 Thu 16:43)
正規表現でマッチした部分が、引数として次項の関数repFuncに暗黙的に渡されます。
また正規表現の中で括弧を使ってグループ化されている部分が複数あった場合、
そのつど第2引数、…第n引数として渡されます。
例えば文字列"2012/12/27"を年、月、日ごとに分けてrepFuncに引数として渡したい場合、
txt.replace(/(\d{4})/(\d{1,2})/(\d{1,2})/g, repFunc);
function repFunc(date, yyyy, mm, dd) {
(処理)
}
というような処理が可能です。
[15093] .. (2012/12/27 Thu 17:16) web