RegExpによるマッチングでRegExp.lastIndexがundefinedになる理由は何ですか?

このQ&Aのポイント
  • JavaScriptの正規表現によるマッチングで、RegExp.lastIndexがundefinedになる場合があります。
  • この現象は、マッチング結果が取得できたにも関わらず、マッチした位置を示すRegExp.lastIndexが設定されないためです。
  • 原因としては、正規表現がグローバルフラグ(g)を持っており、execメソッドが連続して呼ばれるケースが考えられます。
回答を見る
  • ベストアンサー

マッチするのにRegExp.lastIndexがundefinedになってしまいます!

下のようなJavascriptで、 正規表現でマッチして、その位置を調べたいと思います。 しかし・・・マッチはするものの、 肝心の位置(RegExp.lastIndex)が、undefinedになります・・・。 var str = "ABCDEFG"; var rex = new RegExp("C", "i"); if (str.match(rex)) { document.write(RegExp.lastIndex+"文字目にマッチ。"); } else { document.write("マッチしません。"); } どうしてなんでしょうか?? ちなみに、実際のスクリプトはもっと長いものですがそこでうまくいかないので・・・。 今回のソースは、適当なサンプルをとってきて、それを編集したものです。 そのサンプルでも動かないので・・・。ブラウザがおかしいんでしょうか? 一応、Firefox3とGoogleChromeで確認しましたが、やはりundefinedです・・・

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

javascriptの実装の違いですね lastIndexは、RegExpオブジェクトをあらためインスタンスのプロパティ になりました。 また、グローバルサーチを指定する必要があります。 https://developer.mozilla.org/ja/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/lastIndex 共通で動かすにはちょっとした場合分けをすればいいでしょう。 <script> var str = "ABCDEFG"; var rex = new RegExp("C", "gi"); if (rex.exec(str)) { var num=rex.lastIndex; if(!num) num=RegExp.lastIndex; document.write(num+"文字目にマッチ。"); } else { document.write("マッチしません。"); } </script>

masapiyochan
質問者

お礼

おお。ありがとうございます!! なるほど、実装が違うのですね。 私もまだまだ勉強が足りませんでしたね・・・。

関連するQ&A

  • RegExpでカンマの判定で疑問があります。

    下記のようなjavascriptで入力チェックを考えています。 だいたい意図通りに動くのですが、「,」を入力した場合、想定はfalseなのですが、trueになってしまいます。 何か見落としがあるのでしょうか。また理由がわからないため、下記に指定していないのに意図せずにtrueになる文字がないか心配です。 どなたかアドバイスを頂けないでしょうか。 ※ いまはカンマだけ個別に比較して対応しています。 function test() { var str = sample8.input1.value; var check = new RegExp("[ !\"#$%&'()*+-./1023456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz|~アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォャュョッー゛゜。「」、・]"); if (str.match(check)) { alert("true"); } else { alert("false"); } }

  • javascript で undefinedと表示されます

    全ての変数、配列に alert(typeof variable); を試しましたが undefinedが見つかりません。 function a{ var lastdayArray = new Array ('','31','28','31','30','31','30','31','31','30','31','30','31'); var weekArray = new Array ('日','月','火','水','木','金','土'); var a = new Date(); var b = new Date(); var mymonth = a.getMonth()+1; var nextmonth =mymonth +1 ; var myyear = a.getYear()+1;   var today = a.getDate(); var maxbox = 36; var sday = a.setDate(1); var nday = b.setDate(1); var nmonth = b.setMonth(mymonth); var nwday = b.getDay(); var fwk = a.getDay(); var nfday = 6 - nwday; var fline = 6 - fwk; var nextlsday = lastdayArray[mymonth]; var lsbox = (fwk + lastdayArray[mymonth]) +1; var monthArray = new Array(mymonth,nextmonth); var monthflg = new Array(fwk,nfday); var nextflg = new Array(fline,nwday); var s_no0 = 1;   var s_no1 = 1; //数値代入変数       var s_no2 = 1; var s_no3 = 0; var s_no4 = 0; var s_no5 = 0; var s_no6 = 0; var s_no7 = 0; var s_no8 = 0; var schedule_no = new Array(s_no0,s_no1,s_no2,s_no3,s_no4,s_no5,s_no6,s_no7,s_no8); var s_str0 = 'a'; var s_str1 = 'a'; //文字列代入変数 var s_str2 = 'a'; var s_str3 = 'a'; var s_str4 = 'a'; var s_str5 = 'aa'; var s_str6 = 'a'; var s_str7 = 'a'; var s_str8 = 'a'; var schedule_str = new Array(s_str0,s_str1,s_str2,s_str3,s_str4,s_str5,s_str6,s_str7,s_str8); for(var x = 0; x < 2; x++){ daycount = 0; document.write(monthArray[x] + '月の予定'); if(nmonth == 12){nmonth = 0;} document.write('<table width="73%" height="337" border="1" cellpadding="1" cellspacing="1">'); //曜日出力 document.write('<tr>'); for(var l = 0 ; l <= 6; l ++){ if(l == 0){ weekArray[l] = (weekArray[l].fontcolor('#ff1493').fontsize(4)); } else if(l == 6){ weekArray[l] = (weekArray[l].fontcolor('#87ceeb').fontsize(4)); } document.write('<td>' + weekArray[l] +'</td>');} document.write('</tr>'); //曜日を判定しテーブル出力 document.write('<tr>'); //空ボックス出力 if((monthflg[x]) != 6 ){ for(var k = 0; k < (monthflg[x]); k++){ document.write('<td>' + '&nbsp;' +'</td>'); } } if((monthflg[x]) == 0){ for(var y = 0; y < 6 ; y++){ document.write('<td>' + '&nbsp;' +'</td>'); } if((schedule_no[y]) === daycount){ daycount ++; document.write('<td>' + daycount + schedule_str[y] +'</td>'); } else { daycount ++; document.write('<td>' + daycount +'</td>'); } } else{ //空ボックスの数~土曜日まで出力 for(var m =0 ; m <= nextflg[x]; m++){ if((schedule_no[m]) === daycount){ daycount ++; document.write('<td>' + daycount + schedule_str[m] +'</td>'); } else { daycount ++; document.write('<td>' + daycount +'</td>'); } } } document.write('</tr>'); //行出力 for(var i =0 ; i < 4; i++){ document.write('<tr>'); //列出力 for(var j =0 ; j < 7; j++){ if(daycount < lastdayArray[monthArray[x]]){ daycount ++; document.write('<td>' + daycount +'</td>'); } else{ document.write('<td>' + '&nbsp;' +'</td>'); } } document.write('</tr>'); } //最終行出力 if(daycount < lastdayArray[monthArray[x]]){ document.write('<tr>'); for(var p =0 ; p < 7 ; p++){ if(daycount < lastdayArray[monthArray[x]]){ if((schedule_no[p]) === daycount){ daycount ++; document.write('<td>' + daycount + schedule_str[p] +'</td>'); } else { daycount ++; document.write('<td>' + daycount +'</td>'); } } else{ document.write('<td>' + '&nbsp;' +'</td>'); } } document.write('</tr>'); } document.write('</table>'); } }

  • RegExp n番目のrightContext

    RegExp n番目のrightContext をしたいのですがどう書いたら良いでしょうか。 例えば var hoge = ieobj.document.all(0).innerHTML; hoge.match(/html/igm); var result = RegExp.rightContext; で出力されるresultは最後にhtmlにマッチしたものが出ると思います マッチ対象が複数あった場合指定することは可能でしょうか 実際はエラーになりますが RegExp.$n.rightContext の様な事がやりたいのです

  • ECMAScript:RegExp.exec()メソッドについて

    初めて投稿します。 var re = new RegExp("A", "g"); var res = "ABABAB".match(re); document.writeln(res); 上記のように、文字列に対してString.match()メソッドを使用して正規表現(gフラグつき)とマッチングを行うと結果は 「A,A,A」 とマッチしたAが全て配列として帰ってきますが、 var re = new RegExp("A", "g"); var res = re.exec("ABABAB"); document.writeln(res); 上記のように、文字列に対してregExp.exec()メソッドを使用して正規表現(gフラグつき)とマッチングを行うと結果は 「A」 とマッチしたAが1つしか帰ってきません。 ECMA 262 3rd Editionの仕様では、 (http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/) RegExp.exec()メソッドも、String.match()メソッドと同様に、regExpのオブジェクトを生成時に"g"フラグを付加して、ある文字列とマッチングすると、マッチするものが1件以上存在する場合、新しい配列にマッチしたもの全てを各要素に格納して値を返す動作を行うと(多分?)書かれているみたいなのですが、RegExp.exec()メソッドは、どのブラウザで操作を実行しようとしても、マッチした文字が1件しか帰ってきません。。。 教えていただきたいのは、 『何故、RegExp.exec()メソッドはマッチした文字が1件しか帰ってこないか?』です。 いろんなサイトを調べてみたのですが、どうしてRegExp.exec()メソッドがこのようなふるまいを起こすか断定できませんでした。。。 どなたか、JavaScriptやECMAScriptのロジカル的な部分で詳しい方がいらっしゃいましたら、 よろしくお願いいたします。m(__)m

  • JavascriptからJavaへの変え方

    Javascriptで作ったものをJavaにしないといけなくなったのですが 私はJava初心者でまったくわかりません。 色々ネットで調べてみたのですが、どうも難しくて理解することができませんでした。 下にJavascriptで作ったものを載せてるのですがどなたかやり方を教えてもらえないでしょうか? <html> <head> <title>サンプル</title> <script type="text/javascript"> function jikoku() { dd = new Date(); document.F1.T1.value = dd.toLocaleString(); window.setTimeout("jikoku()", 1000); } </script> <script type="text/javascript"> mes = new Array(5); mes[0]="0"; mes[1]="1"; mes[2]="2"; mes[3]="3"; mes[4]="4"; date=(new Date()).getHours(); if( 0 <= date && date <= 5 ){ document.write(mes[0]); } else if( 6 <= date && date <= 10 ){ document.write(mes[1]); } else if( 11 <= date && date <= 16 ){ document.write(mes[2]); } else if( 17 <= date && date <= 19 ){ document.write(mes[3]); } else{ document.write(mes[4]); } </script> <script type="text/javascript"> function Random() { var kazu = Math.random(); kazu = kazu*100; kazu = Math.ceil(kazu); if( kazu<=9 ) document.write('<br/>○1<br/>'); else if( kazu<=19 ) document.write('<br/>○2<br/>'); else if( kazu<=29 ) document.write('<br/>○3<br/>'); else if( kazu<=39 ) document.write('<br/>○4<br/>'); else if( kazu<=49 ) document.write('<br/>○5<br/>'); else if( kazu<=59 ) document.write('<br/>○6<br/>'); else if( kazu<=69 ) document.write('<br/>○7<br/>'); else if( kazu<=79 ) document.write('<br/>○8<br/>'); else if( kazu<=89 ) document.write('<br/>○9<br/>'); else document.write('<br/>○10<br/>'); } Random() </script> <script language="JavaScript"> var imglist = new Array( "sample1.jpg", "sample2.jpg", "sample3.jpg", "sample4.jpg" ); var selectnum = Math.floor((Math.random() * 100)) % imglist.length; var output = "<img src=" + imglist[selectnum] + ">"; document.write(output); </script> </head> </html>

  • undefinedを表示させない方法はありますか?(javascript)

    undefinedを表示させない方法はありますか?(javascript) コードを入力して、文字を表示させているのですが、 以下のソースになります。 その時に、イベント処理をonkeyupにしていて、 入力しているのと同時に表示させています。 その時に、1とか10とか入力している途中に、 undefinedが表示されてしまいます。 空白でもいいのですが、表示させない方法はありますか? 教えて下さい。 <SPAN>とinnerHTMLを使用しています。 <HTML> <BODY> <SCRIPT LANGUAGE=JavaScript> <!-- function sample(f) { var sample = new Array() sample['100'] = 'りんご' ; sample['101'] = 'オレンジ' ; sample['102'] = 'メロン' ; document.getElementById('ans').innerHTML = sample[f.code.value] ; } // --> </SCRIPT> <FORM NAME=f> <INPUT NAME=code SIZE=4 onkeyup="sample(this.form)"> <SPAN ID="ans"></SPAN> </FORM> </BODY> </HTML>

  • func.arityで、undefined

    とほほのjavascriptで勉強しているのですが http://www.tohoho-web.com/js/function.htm 関数オブジェクトのfunc.arityのところ 関数が要求する引数の個数を返します。 とあるのに、 function goukei(a, b, c) { return(a + b + c); } n = goukei.arity; document.write(n); このコードを書いて実行しても 引数の個数の3ではなく、undefinedが表示されます。 ちゃんと引数は3個だし、functionで定義した関数も、document.write文の前に宣言してあり ぱっとみ問題ないように思われるのですが、どうしてundefinedと表示されるのでしょうか。

  • AJAXの計算式の中にIF文を入れて表示したい

    下記の2つのファイルで、フォームから入力した数値同士の「足し算の結果」をAJAXで表示できます。 ******************************************** 【HTMLフォーム】 <script language="JavaScript" type="text/javascript" src="js/culc.js"></script> <form name="f1"> <input type="text" id="text1" name="text1" size="10" maxlength="10" /> + <input type="text" id="text2" name="text2" size="10" maxlength="10" /> <input type="button" value="足す" onclick="readText()" /> </form> <p id="message"></p> ******************************************* 【JAVASCRIPT(culc.js)】 function readText() { var text1 = document.getElementById("text1"); var text2 = document.getElementById("text2"); var message = document.getElementById("message"); var str_val1 = text1.value; var str_val2 = text2.value; var sum; if (isNaN(str_val1) || str_val1 == "" || isNaN(str_val2) || str_val2 == "") { textMessage = "数値以外の文字が入っています"; } else { //sum = str_val1 + str_val2; sum = parseFloat(str_val1) + parseFloat(str_val2); textMessage = "合計は、" + sum + "です"; } message.innerHTML = textMessage; } ************************************************ 【質問】 このjavascriptを改造し、入力した数値についての「足し算の結果」が正の数だった場合には「正の数」、負の数だった場合は「負の数」と表示すべく改造しております。下記の改造を施したのですが、うまく表示されません。 下記の文のどこが誤りか修正頂けませんでしょうか? 宜しくお願い致します。 【JAVASCRIPT(culc2.js)】 function readText() { var text1 = document.getElementById("text1"); var text2 = document.getElementById("text2"); var message = document.getElementById("message"); var str_val1 = text1.value; var str_val2 = text2.value; var sum; if (isNaN(str_val1) || str_val1 == "" || isNaN(str_val2) || str_val2 == "") { textMessage = "数値以外の文字が入っています"; } else { //sum = str_val1 + str_val2; sum = parseFloat(str_val1) + parseFloat(str_val2); textMessage = "(if((sum > 0) { document.write("正の数"); } else((sum <= 0) { document.write("負の数"); } ))"; } message.innerHTML = textMessage; }

    • ベストアンサー
    • AJAX
  • JavaScriptのコードの間違いを教えて

    いつもお世話になっております。 現在、JavaScriptの勉強をしているのですが、if構文のところでつまずいてしまいした。 下のコードがうまく実行できません。 間違いを指摘して頂ければと思います。 <doctype! html> <html lang="ja"> <head>    <meta charset="UTF-8">    <title>Javascript</title> </head> <body> <script type="text/javascript">    var x = window.prompt("好きな値を入力してください","100");    if (x>100)       {window.document.write("100より大きいです");}    else {if(x<100))       {window.document.write("100より小さいです");}       else {if(x=100))          {window.document.write("100です");}       }    } </script> </body> </html> なお、テキストエディタで記述し、実行はGoogleChromeで行いました。 よろしくお願いします。

  • このコードを処理速度向上させることはできますか?

    このコードを処理速度向上させることはできますか? <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> //<![CDATA[ function className(str){ var alltag = document.getElementsByTagName("*"); var ary = []; for(var i=0;i<alltag.length;i++){ if("."+alltag[i].className == str){ ary.push(alltag[i]); } } return ary; } window.$ = function(str){ var ID = str.match(/^#(\w+)/), CLASS = str.match(/^\.(\w+)/), TAG = str.match(/^(\w+)|(\*)/), node = str.match(/^doc/)? document: TAG? document.getElementsByTagName(RegExp.$1==""?RegExp.$2:RegExp.$1): ID? document.getElementById(RegExp.$1): CLASS? navigator.appVersion.toLowerCase().indexOf("msie")? className(str): document.getElementsByClassName(RegExp.$1): null; this.style = function(css){ css = css.split(/\:|\;/); if(ID){ for(var j=0;j<css.length;j++) node.style[css[j].replace(/\s+/g,"").replace(/\-(\w)/,function($1){$1=$1.substr(1);return $1.toUpperCase()})] = css[j+1]; }else{ for(var i=0;i<node.length;i++){ for(var j=0;j<css.length;j++) node[i].style[css[j].replace(/\s+/g,"").replace(/\-(\w)/,function($1){$1=$1.substr(1);return $1.toUpperCase()})] = css[j+1]; } } } return this; } window.onload = function(){ var st = new Date().getTime(); for(var i=0;i<10000;i++){ $('#wrap').style("color:#00f; background:#f00; border-left:10px solid #000;"); $('div').style("border-right:10px solid #000; width:100px; height:100px; margin:10px;"); $('.cl').style("border-top:10px solid #000; background:#00f;"); } var end = new Date().getTime(); alert(end-st); } //]]> </script> <title></title> </head> <body> <div id="wrap">aaaaa</div> <div class="cl">bbb</div> <div class="cl">ccc</div> </body> </html> 他にも、もっとこうしたほうが…等ありましたら教えてください。どうか宜しくお願いします。