JavaScript正規表現での日本語マッチ

[上に] [前に] [次に]
ふじ [E-Mail] 1999/12/30(木) 09:21:45
JavaScriptの正規表現について質問させて下さい。
2バイト文字でマッチさせようとして、はまってしまいました。

Win95(OSR2) + IE4.01 では問題無いのですが、NN4.6で、

"あいうえお".match(/あい/);
"あいうえお".search(/うえ/);

こんな風に 2文字以上でマッチさせようとしても、マッチしてくれない
ようなのです。1文字だけなら大丈夫で、

alert("あいうえお".match(/う/));
alert("あいうえお".search(/う/));

これらは正常に動作します。


re = new RegExp("あい");
alert("あいうえお".match(re));
等としても駄目でした。
# 1バイト文字のみでのマッチは、NN でも問題有りません。

何か私、考え違いしてますでしょうか。
情報が有りましたら御教示下さい。

zizz... [HomePage] 1999/12/30(木) 12:03:25
私のWindows98のNetscape 4.7 [en]も同じ動作をします。
今まで正規表現を避けて通ってきたので、詳しいことは知りません。
原因はまだ分かりませんが、調べた結果を報告します。

----- 解析用ソース -----
var str = "";
var re = /あ/;
var ar = re.exec("あいうえお");
for(i in re) {
  str += i + ":" + re[i] + "\n";
}
str += "\n";
for(i in ar) {
  str += i + ":" + ar[i] + "\n";
}
----- ここまで -----
結果:

Netscape 4.7
-----
source:あ
global:false
ignoreCase:false
lastIndex:0

0:あ
index:0
input:あいうえお
-----
MSIE 5.0
-----

input:あいうえお
index:0
lastIndex:1
0:あ
-----
Mozilla M12
-----
source:あ
global:false
ignoreCase:false
lastIndex:0
multiline:false

0:あ
index:0
input:あいうえお
-----

var re = /あい/; とした結果:
Netscape 4.7
-----
source:あい
global:false
ignoreCase:false
lastIndex:0


-----
MSIE 5
-----

input:あいうえお
index:0
lastIndex:2
0:あい
-----
Mozilla M12
-----
source:あい
global:false
ignoreCase:false
lastIndex:0
multiline:false

0:あい
index:0
input:あいうえお
-----

Netscape 4.7の動作は明らかにおかしい。MSIEも少し変。
今のところM12が一番まともな動きをしている。

zizz... [HomePage] 1999/12/30(木) 12:16:49
補足。
上の実験は
http://developer.netscape.com/docs/manuals/js/core/jsref/regexp.htm#1194735
のexampleをもとにした。
結果はTEXTAREAに吐き出させ、コピー。
M12はまだコピーが出来ないようなので、自力で移した。

var re = /あい/ の時、Netscapeではarがnullだった。

# 見難いですね。すみません。

三原克大 [E-Mail] 1999/12/31(金) 22:34:08
なんだかいやーな予感がします。

JavaScript と ECMA-262 は違うのですが、
ECMA-262 の国際化スキームでは
  文字列リテラルとコメント以外は
  Unicode 2.0 の内の最初の 127 文字のみ
  を用いて構成する
と定められています。

これだと、RegExp オブジェクトの定義が
ソースコード内で出来ません。
どうなっているかなと考えると、
  RegExp は ECMA-262 に無い
  JavaScript 独自のオブジェクト

で、次のような疑問が。
  各ブラウザに搭載されているパーザが
  ECMA-262 を満たして事足れりとしていたら

いやーな感じです。

三原克大 [E-Mail] 2000/01/01(土) 10:42:35
試しもせずにものを書いてすみませんでした。

new RegExp() を用いて実験して、
zizz... さんと同じ結果を得ました。
以下に実験に使ったソースコードを紹介します。

var re = new RegExp("\u3042");
// "\u3042" == "あ"
var aiueo = "\u3042\u3044\u3046\u3048\u304a"
// "\u3042\u3044\u3046\u3048\u304a" == "あいうえお"
var ar = re.exec(aiueo);
document.writeln("re: " + re.toString() + "<br>");
document.writeln("aiueo: " + aiueo + "<br>");
document.writeln("<br>");
for(i in re) {
  document.writeln(i + ": " + re[i]  +"<br>");
}
document.writeln("<br>");
for(i in ar) {
  document.writeln(i + ": " + ar[i] + "<br>");
}
document.close();

zizz... [HomePage] 2000/01/01(土) 13:43:18
ECMAScript 3で正規表現は追加されています。
しかしECMAScript 3はまだFinal Draftで、
NetscapeがJavaScript 1.2を出したとき、まだ登場していなかったと思います。(多分)
http://www2.hursley.ibm.com/tc39/ecma262-3.pdf
この文書で正規表現について触れられているのですが、勉強不足でnon-ASCIIの扱いがよくわかりません。
とりあえず、Regular Expression Literal /pattern/flags のpatternはいけるみたいです。(7.8.5)

調べていて見つけた文書。(あまり関係なさそうだけど)
http://www.mozilla.org/js/UnicodeIdentifiers.html

三原克大 [E-Mail] 2000/01/01(土) 20:07:51
助かった・・・

引用
Non-Latin Unicode characters are allowed in identifiers, string literals, regular expression literals and comments.
  ECMAScript Language Specification Edition 3 13-Oct-99
   6 Source Text より

仕様の上では機能するように見えます。
後は実装待ちでしょうか。

ふじ 2000/01/04(火) 14:25:58
うーん、こんな風に

var re = new RegExp("\u3042\u3044");
var aiueo = "\u3042\u3044\u3046\u3048\u304a"
var ar = re.exec(aiueo);

unicode で書いてもダメですか。
NN4 ではまともに使えないと思った方が良さそうですね。

zizz... さん、三原克大さん、ありがとうございました。
#しかし参ったなぁ・・・(;_;)

ふじ 2000/01/04(火) 15:09:14
[[解決]]
解決忘れました。

たこすけ 2000/01/04(火) 23:33:57
> 2文字以上でマッチさせようとしても、マッチしてくれない
ちょっと実験してみたのですが
量指定子を付ければ良いみたいです。(面倒だなぁ)

var re = new RegExp("あ{1,1}い{1,1}");
var aiueo = "あいうえお";
var ar = re.exec(aiueo);
とか

"あいうえお".match(/あ{1,1}い{1,1}/)
はマッチしてくれました。(Win98+NC4.06)

逆に量指定子を一切使わない(/あい*う/とかしない)のであれば
escape()を使うのも一つの手段かと・・・ちょい不正確になるけど。

[上に] [前に] [次に]