プログラムを書いていて,今までさっぱりわからなかったのですが,結局正規表現とは何なのでしょうか?
例えば,
/[0-9.‐-]/g
という表現では,「全角を半角に変換(ハイフン、ドット、数字以外を取り除く)」と,とあるサイトで書かれていました.
が,同じ「-」でも,取り除いたり「A〜Z」のように「から」という意味で使われていたりと,複数の意味があるように見えます.
さらに
/(?!^-)[^\d.]/g
のように,もはや私には意味がわかりません.
正規表現の読み方や,詳しい意味などを教えていただけないでしょうか.
よろしくお願いいたします.
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答9件
0
ベストアンサー
参考情報ページを紹介します。
-
正規表現をグラフ化してくれる https://www.debuggex.com/
-
JavaScriptの正規表現をビジュアライズ http://regviz.org/
-
ゼロから正規表現を使えるようになるためのステップ http://qiita.com/seihowlow24/items/79f565f22b9223c6e848
-
正規表現の勉強に役立つリンク http://mi813.hatenablog.com/entry/2015/02/21/112128
-
正規表現とは http://itpro.nikkeibp.co.jp/article/Keyword/20070207/261234/
...
正規表現(せいきひょうげん)とは,ある文字の並びを使って,より複雑な文字の並びを表現する方法です。
最も広く知られている例は「」と「.」でしょう。
「」は直前の文字の0個以上の並びを,「.」は何らかの1文字を表します。
正規表現を使うと,わずかな文字を書き下ろすだけで,柔軟な文字列の表現が可能になります。
これが正規表現を使う理由です。
...
歴史的には1940年代の形式言語論に由来しますが,C言語とUNIXの開発に貢献したKen Thompson氏が1970年前後にQEDというエディタ・ソフトウエア(エディタ),ついでedと呼ばれるUNIX上のエディタに文字列検索用として組み込んだことから,コンピュータの世界でも利用されるようになりました。
...
正規表現は,POSIXの標準,すなわち「POSIX Part2:Shell and Utilities」として標準化されています。
しかし,さまざまなエディタ,プログラミング言語,シェルは,かならずしもPOSIX標準で定められた表現をすべては実装していません。さらに独自に拡張した正規表現も含めています。従って基本的な正規表現を覚えたら,用途に応じて「方言」に習熟する必要があります。
...
- redditから 正規表現: その理論、実装と歴史 http://d.hatena.ne.jp/karasuyamatengu/20090915/1252974459
...
Perlをはじめとするスクリプト言語系とgrep,awkなど伝統的Unixのregexの実装には決定的な違いがある。
前者はbacktrackingを使い、後者はUnix創始者のKen Thompson氏が1960年代に発明したNFAベースのもの。
実は「a?」や単独のキャラクタ「a」が繰り返されるような「特殊」な正規表現だと、Thompson NFA実装の方が桁違いに速い。
...
投稿2015/02/28 07:31
編集2015/03/01 20:28総合スコア22324
0
正規表現には、取り除いたりする機能はありません。「取り除く」等は正規表現を使うプログラミング言語側の機能です。
正規表現は、「文字列の中の一部」を指定する方法です。文字列の一部を指定する場合に、「123文字目から200文字目」などのように文字数位置で指定する方法もありますが、そうではなく、「"A"という文字から"B"という文字が出てくるまで」とか「3桁の数字」というように文字列の内容で文字列の一部を指定する方法です。
例えば/[A-Z]/
だと、「半角英字の大文字1文字」という一部分を指定します。その一部分を削除するのか、取り出すのか、置き換えるのか、などは正規表現で無く、それを使うプログラミング言語側で処理します。
正規表現は、あくまで、「文字列のどの場所なのか」を指定する機能です。
投稿2015/02/28 08:52
総合スコア85778
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/04/18 17:24
0
結局正規表現とは何なのでしょうか?
一言で言うと、
文字列に対する処理を簡潔に記述できる
物です。
例えば以下のように書くと
str = "abc123";
if( str.match(/^[a-z0-9]{1,}$/) ){ /* 何らかの処理 */ }
a~zの半角英字(小文字限定)か半角数字、1文字以上の組み合わせの文字列かという意味になりますが、これをプログラムに起こすとそれなりの行数になります。
lang
1if( isAlnum("abc123") ){ /* 何らかの処理 */ } 2 3function isAlnum(str){ 4 //空文字ならfalse 5 if(str == "") return(false); 6 7 //ASCIIコードを取得 8 var charcd_a = "a".charCodeAt(0); 9 var charcd_z = "z".charCodeAt(0); 10 var charcd_0 = "0".charCodeAt(0); 11 var charcd_9 = "9".charCodeAt(0); 12 13 //1文字ずつチェックする 14 var len = str.length; 15 for(var i=0; i<len; i++){ 16 var c = str.charAt(i); //1文字取出す 17 var cur = c.charCodeAt(0); //取り出した文字の文字コード取得 18 19 if( (charcd_a <= cur && cur <= charcd_z ) || (charcd_0 <= cur && cur <= charcd_9) ){ 20 continue; 21 } 22 else{ 23 return(false); 24 } 25 } 26 27 return(true); 28}
これがたった1行で書けるのは画期的と言えます。
また逐一コードを書いていると、ちょっとした変更でも相当量を書き直す必要が出てくる場合がありますが、正規表現であれば修正対象が1箇所で済む場合もあります。
もちろん、デメリットもあります。
・最初の学習コストがそれなりにある
・複雑な物を書くと
意図しない動作をする場合がある(書き損じに気が付かず)
新人が読めない場合がある
・動作速度的に遅い場合がある
しかし、それ以上に簡潔にかけるメリットは大きいです。
最初はよくわからないかもしれませんが、覚えておいて損はありませんので、ぜひどこかで時間を取って学習されると良いと思います。
投稿2015/02/28 08:46
編集2015/02/28 09:05総合スコア783
0
ご質問の
「正規表現」とは結局なになのか?
に対して、きちんと自分なりに自信のある答えを得るには、やはり「詳説 正規表現」あたりを
ガッツリ読むのが良いと思いますが、以下に、あくまで私個人のイメージを書かせて頂きます。
説明のための便宜上、様々な正規表現の中でも、まずは
「^ で始まり、$で終わるもの」
に話を限定させてください。つまり、まずは**正規表現「^ ・・・ $」とは何か?**という問い
から始めます。
これに対する私の答えは、
ある条件を満たす文字列の集合(を 、文字列で表現したもの)
というものになります。なお、ここでいう「集合」とは、数学で習う集合(Set)のことです。
以下、簡単な例を挙げて、説明します。
たとえば
^5[0|2|4|6|8]$
という正規表現は、十の位が5、一の位が偶数であるような二桁の整数を表す文字列の集合
A = { “50”, “52”, “54”, “56”, “58” }
を表していると考えることができます。上記の集合Aを定義する式は、プログラミング言語に
よるコードではなく、あくまで数学的な記号によって集合Aを定義する数式と思ってください。
ポイントとしては正規表現、
^5[0|2|4|6|8]$
を左から右へ読み進めるにしたがって、今の例でいうと、”50” や”52”といった文字列が、
「集合Aの要素として生み出される」もしくは、よりプログラマーっぽい「生成される」
という言葉を使って、「集合Aの要素として"50"や"52"が、生成される」という
イメージを持つことが肝心だろうと思います。
この例だと、条件にあう文字列の個数は、つまり集合Aの要素数は5個と簡単に
列挙できる有限個ですから、正規表現を使わなくても、たとえば配列を使って
(※以下、コード例はすべてJavaです。)
lang
1String[] arrayOfA = {"50", "52", "54", "56", "58" };
というふうに書けますが、もっとずっと要素数の多い集合や、(可算ではあるが)無限個の
要素を持つ集合も考えられますよね。たとえば、集合Bを
B = { x | x は半角小文字のアルファベットだけから構成され、かつ、長さ3文字の文字列 }
とすると、集合Bの要素数は何個になるかというと、26の3乗で17576個という個数になり、
さきほどのAのように、プログラムの中でこんなコード
lang
1String[] arrayOfB = { “aaa”, “aab” … , “zzz” }; // 17576個、全部並べて書きます?
で、すべてを列挙して書くなんてことは、とてもやっていられないですよね。
しかし、正規表現を使えば、
lang
1String regExpOfB = "^[a-z]{3}$";
と書けまして(javaでは、前後の/ は不要です。)、この regExpOfB が
集合Bを、要素を列挙していなくても、実質的に表していることになっている、
あるいは、集合論の用語でいえば正規表現 ^[a-z]{3}$ は、集合Bの
内包的記法をプログラムコードとして書ける形にしたものである、というのが
私の正規表現の理解の仕方です。
※集合の「内包的記法」については、以下をご参照ください。
集合の記述法(集合 - Wikipedia)
上記のように、正規表現 「^ ・・・ $」を
ある条件を満たす文字列の集合(を、文字列で表現したもの)
と考えると、^・・・$に限らず、正規表現とは何かという、最初のご質問に戻ると、
ある条件を満たす文字列を含む文字列の集合(を、文字列で表現したもの)
と考えることができます。
以上、正規表現をマスターする考え方(のひとつ)として、
正規表現とは、ある条件を満たす文字列の集合(を文字列で表現したもの)である。
という考え方を挙げさせて頂きました。
お役に立てましたら幸いです。
投稿2015/03/01 09:55
編集2015/03/01 20:02総合スコア9058
0
/[0-9.‐-]/g
この[]の中の 0-9の-は0から9なのですから
.‐-も素直に、 .から- の意味です 取り除くの意味はありませんし
半角-は合致しません
難しいと思ったのも実は勘違いしているだけかもしれませんよ。
投稿2015/03/03 04:47
退会済みユーザー
総合スコア0
0
[
と]
の間にある-
と、普通の-
は意味が違うんで、
囲われたものと囲われてないものの違いを覚えるだけでダイジョブです。
^
は先頭を意味しますが、[
と]
の中では、除外の意味なります。
投稿2015/03/03 05:47
総合スコア112
0
/[0-9.‐-]/g
はわかりづらいですが1つ目は半角ハイフンで2つ目は全角ハイフンです。
この正規表現は全角の数字0-9
、ドット.
、ハイフン‐
、マイナス-
にマッチします。
?!
は否定先読みと呼ばれるものです。
正規表現/REGEXP/が含まれない行にマッチする正規表現(該当行を削除したい場合に)
/(?!^\-)[^\d\.]/g
は先頭の文字の先頭の半角ハイフンと半角数字、半角ドット以外にマッチします。
以下のサイトでは正規表現を解析し、視覚化してくれるので理解の手助けになります。
Regexper
追記
これらだけでは置換はできません。
例えばJavascriptであれば以下のうようにreplaceを利用すれば置換できます。
lang
1newString = str.replace(/[0-9.‐-]/g, function(w){ 2 return w + "@";//マッチした文字の後ろに@付与 3});
投稿2015/02/28 07:07
編集2015/02/28 07:53総合スコア3541
0
「正規表現」は、規則のある文字列を探したり置き換えたりする表現方法で、プログラムの中で使われますが、どのプログラム言語の「正規表現」も似ていますが、同じではありません。
「正規」という言葉から「普遍的に正しい」みたいな意味を感じますが、結局、言語毎に正規表現があってそれを覚える必要が出てきます。なので理解をする事は時間と努力の無駄、正規表現事例集を見ながら書けば十分だと考えます。
「正規」なんて幻想だと思いますよ。
投稿2015/03/01 12:19
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/03/01 14:06
2015/03/02 01:53
2015/03/03 04:02
2015/03/03 09:09
2015/03/03 09:13
2015/04/18 17:27
0
こんにちは。
以前、このご質問の回答に
ある条件を満たす文字列の集合(を 、文字列で表現したもの)
と書かせて頂きましたが、このような捉え方で、より詳しく説明している文章を
(超絶スゴいハッカーが創設者のプロジェクト内に、)みつけたので参考のため
追記させて頂きます。
-
GNU プロジェクト のホームページに行く。
-
画面上の「ソフトウェア」をクリックして、GNUソフトウェアのページに行く。
-
画面下のほうに様々なソフトウェアのリンクのうち「退役したGNUパッケージ」にある、
regex をクリック
- 説明に
… see also the Regular expressions chapter in the Gnulib manual, …
とあるのに従って、gnulib の正規表現の章に行く。
-
Overview をクリック
-
冒頭に以下のように書かれています。
A regular expression (or regexp, or pattern) is a text string
that describes some (mathematical) set of strings.
A regexp r matches a string s if s is in the set of strings described by r.
また、元のドキュメント、GNU regex 0.12のマニュアルを
和訳してくださっている方がいらっしゃいました。
ホームページにリンクフリーとあったので、上記のOverview の
和訳のリンクを貼らせていただきます。
http://www.kt.rim.or.jp/~kbk/regex/re_1.html#SEC1
以上です。ご参考まで。
投稿2015/05/07 07:16
編集2015/05/07 07:17総合スコア9058
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/04/18 17:19