[ 掲示板に戻る ]

記事No.10571に関するスレッドです

String.match の肯定後読み検索 / ぶぶまる
macOS 10.13.6
InDesign CC2018

ESTKでスプリプト勉強中しています。
数値ばかりの表組の小数点以上と以下のそれぞれの桁数を知りたいと思ってます。
String.matchメソッドを使って、スクリプトを書いてみましたが、
肯定後読み検索の結果がnullになります。
inDesignの正規表現検索で検索文字列を
(?<=\.)\d+
にすると期待通りに検索してくれます。

どうしてなのか分かりません。。。
どうかお知恵をお貸しいただけないでしょうか?
よろしくお願いします。

function myMes(mes){
$.writeln(mes);
}

//表の列を選んでないとエラーにする

var mySel = app.activeDocument.selection[0];

//myMes(mySel.constructor.name);

var myAry = [];
var myLeft = [];
var myRight = [];

for(i=0; i<mySel.cells.length; i++){

myCell = mySel.cells[i].texts[0].contents;

myAry.push(myCell);
}

myMes(myAry);

//セル内に改行がある場合はエラーの予定
//少数点が2つ以上ある場合のエラー処理が必要

for(j=0; j<myAry.length; j++){

myLeft.push(myAry[j].match(/^[\d|\s]+/g));

myRight.push(myAry[j].match(/(?<=\.)\d+/g));
}

myMes(myLeft);
myMes(myRight);

No.10571 2024/04/22(Mon) 16:20:27
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15

Re: String.match の肯定後読み検索 / miyaji
バージョンは間違えているかもしれませんが、ESTKが対応しているECMAScriptのバージョンは3で、肯定(否定)後読みが対応されたのがECMAScriptのバージョンは9なので、使用できなかったはずです。

InDesignの正規表現での検索であれば肯定後読みに対応しているので、下記で求められるかと思います。(小数点より右を求める部分のみ記述しています)

app.findGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = '(?<=\\.)\\d+';
var res = mySel.findGrep();
for(var i=0 ; i<res.length ; i++){
myRight.push(res[i].contents);
}
myMes(myRight);

No.10572 2024/04/22(Mon) 17:31:14
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0

Re: String.match の肯定後読み検索 / miyaji
小数点を含めて検索してよければ、下記でも求められます。

myRight.push(myAry[j].match(/\.\d+/g)[0].replace(/\./,""));

No.10573 2024/04/22(Mon) 17:45:58
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0

Re: String.match の肯定後読み検索 / ぶぶまる
miyaji さま

お返事&ご回答ありがとうございます。
JavaScriptの仕様バージョンが原因でしたか。。。
仕様を調べるという選択肢がまったく頭に浮かびませんでした。。。

ご回答いただいた「InDesignの正規表現での検索」を試してみます。
何度がサンプルスクリプトで拝見したことはありますが、
実際に使うのは初めてなので、
うまくいったら、報告させてもらいます。

今回は本当にありがとうございました。

No.10574 2024/04/23(Tue) 09:31:35
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15

Re: String.match の肯定後読み検索 / (z-)
InDesignの正規表現検索機能の利用は自分も乱用しております。
あえてExtendScriptだけで、ちょっとやってみました。
あくまで一例ということで。
−−−−−−−−−−−−−−−−−−−−−
var myLeft, myRight, num;
var str = "123.456"; // テスト用文字列

if(/^[0-9]+(\.[0-9]+)?$/.test(str)){
num = str.split("."); // 小数点で分割
try{ // 小数点なしの場合myRightでエラー出るので対策
myLeft = num[0];
myRight = num[1]; // 小数なければundefinedのまま
} catch(e){}

$.writeln("myLeft: " + myLeft);
$.writeln("myRight: " + myRight);
} else{
$.writeln("だめな文字列です");
}

No.10576 2024/04/24(Wed) 12:45:39
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6.1 Safari/605.1.15

Re: String.match の肯定後読み検索 / ぶぶまる
miyaji さま

ご教示しただいた「InDesignの正規表現での検索」バージョンで
少数点以下の数値を抽出することができました。
以下、はString.match バージョンの現状報告です。
コメントアウトで冗長になって申し訳ございません。。。

あと、
(z-)さま

お返事ありがとうございます。
ねちねち解説は常に参考にしています。
当初、「年表記を「202x(令和x)年」に整形するやつ」を拝見して
split を試したんですが、小数点なしの場合にあたる10でエラーがでて、
すぐに諦めてしまいました。。。
今回、ご教示いただいたやつを今から精読して参考にさせてもらいます。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

function myMes(mes){
$.writeln(mes);
}

var mySel = app.activeDocument.selection[0];

var myAry = [];
var myLeft = [];
var myRight = [];

for(i=0; i<mySel.cells.length; i++){

myCell = mySel.cells[i].texts[0].contents;

myAry.push(myCell);

}

myMes(myAry);

for(j=0; j<myAry.length; j++){

myLeft.push(myAry[j].match(/^[\d|\s]+/g));

}

myMes(myLeft);

/*
以下は、小数点以下を抽出してくれました。

miyaji さま
感謝します!!!!

なんとなく、myLeft のように
myAry と配列の要素数を合わしたい気がしましたので
ちょっと保留します。


app.findGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = "(?<=\\.)\\d+";

var res = mySel.findGrep();

for(var k=0 ; k<res.length ; k++){

myRight.push(res[k].contents);

}

myMes(myRight);
*/

/*
以下は、myAry[3] でエラーっぽいです。
String.matchメソッドは、配列の要素が 空(null?) だとダメ?

for(k=0; k<myAry.length; k++){

myRight.push(myAry[k].match(/\.\d+/g)[0].replace(/\./,""));

}
*/

/*
以下は、
myAry[6]の10でエラーっぽいです。
そもそもreplaceするのもがないからダメ?

for(k=0; k<myAry.length; k++){

if(myAry[k] == "") {continue;

} else {

myRight.push(myAry[k].match(/\.\d+/g)[0].replace(/\./,""));
}
}
*/

No.10577 2024/04/24(Wed) 15:48:28
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15

Re: String.match の肯定後読み検索 / (z-)
>ねちねち解説
わあ、あんなもん参考にしていただいてすみません。ねちねちしすぎてて読みづらすぎますよね…
まだESTKをお使いでしたらこれもあわせてどうぞ。大雑把な使い方をまとめたものです。同様に読みにくいです。12年前だ…
https://ajabon.catfood.jp/?p=1065

> 小数点なしの "10" でエラー
については、そのときMyRight はどうすればよいのか不明だったので、とりあえず以下の感じです。
num = str.split("."); により、
str が "123.456" なら ["123", "456"] に、
"10" なら ["10"] となります。
とりあえず myLeft には確実に値が入ります。
myRight に代入の際、num の要素数が足りずエラーとなります。
それを try〜catch で雑に回避しています。

ESTKのブレークポイントで止めて、ステップオーバーで1行ずつ送り、変数の値挙動、および型の挙動を見つめましょう。
また、要件を固めていきましょう。「この場合、この変数はこうなってほしい」の「この場合」を煮詰め切ったら適切なコードが浮かんでくるはずです(たぶん…)

No.10578 2024/04/24(Wed) 17:38:47
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6.1 Safari/605.1.15

Re: String.match の肯定後読み検索 / ぶぶまる
miyaji さま
(z-)さま

アドバイスいただいたおかげで思うような結果の出る
スクリプトが書けました。

z-)さま著のデバッグの手引きも参考に煮詰めさせてもらいました。
予想外の二重配列の出現には、ずいぶん手こずりました。。。

今回はありがとうございました!
また,よろしくお願いします。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
function myMes(mes){
$.writeln(mes);
}

var myLeft = [];
var myRight = [];
var myAry = [];
var mySplt = [];
var Lleng = [];
var Rleng = [];

var mySel = app.activeDocument.selection[0];

// 選択したセルの数値を配列myAryに代入
for(i=0; i<mySel.cells.length; i++){

myCell = mySel.cells[i].texts[0].contents;

myAry.push(myCell);

}

// 配列myAryの数値を小数点の右側・左側で分けて配列mySpltに代入
for(i=0; i<myAry.length; i++){

// 小数点があるとき、\s は三桁スペース
if(/^[0-9|\s]+\./.test(myAry[i])){

// 小数点で分割、予想外の二重配列!!
mySplt.push(myAry[i].split("\."));

}else{
// 小数点がない数値の場合
if(/^[0-9|\s]+$/.test(myAry[i])){

// 要素と空の要素をPush、これは無理矢理、二重配列に
mySplt.push([myAry[i],""]);
}
}
}

// 配列mySpltを小数点の左側と右側にそれぞれ配列として分けて
// 桁数を Lleng と Rleng に配列として代入

for(i=0; i<mySplt.length; ++i){

Lleng.push(mySplt[i][0].length);

Rleng.push(mySplt[i][1].length);

}

myMes("左の最大桁数は "+myMax(Lleng)+"(3桁スペース含むので要注意)");

myMes("右の最大桁数は "+myMax(Rleng));

//ここからLlengとRlengの最大値を知りたい!

function myMax(myDigits){

var max = myDigits[0];

for(i=1; i < myDigits.length; ++i){

if( max < myDigits[i] ){

max = myDigits[i];
}
}
return max;
}

No.10581 2024/04/26(Fri) 13:19:40
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15