質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

9回答

6743閲覧

「正規表現」とは結局なになのか?

nnahito

総合スコア2004

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

27クリップ

投稿2015/02/28 05:59

プログラムを書いていて,今までさっぱりわからなかったのですが,結局正規表現とは何なのでしょうか?

例えば,
/[0-9.‐-]/g
という表現では,「全角を半角に変換(ハイフン、ドット、数字以外を取り除く)」と,とあるサイトで書かれていました.
が,同じ「-」でも,取り除いたり「A〜Z」のように「から」という意味で使われていたりと,複数の意味があるように見えます.

さらに
/(?!^-)[^\d.]/g
のように,もはや私には意味がわかりません.

正規表現の読み方や,詳しい意味などを教えていただけないでしょうか.
よろしくお願いいたします.

abyss👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答9

0

ベストアンサー

参考情報ページを紹介します。

...
正規表現(せいきひょうげん)とは,ある文字の並びを使って,より複雑な文字の並びを表現する方法です。
最も広く知られている例は「」と「.」でしょう。
」は直前の文字の0個以上の並びを,「.」は何らかの1文字を表します。
正規表現を使うと,わずかな文字を書き下ろすだけで,柔軟な文字列の表現が可能になります。
これが正規表現を使う理由です。
...
歴史的には1940年代の形式言語論に由来しますが,C言語とUNIXの開発に貢献したKen Thompson氏が1970年前後にQEDというエディタ・ソフトウエア(エディタ),ついでedと呼ばれるUNIX上のエディタに文字列検索用として組み込んだことから,コンピュータの世界でも利用されるようになりました。
...
正規表現は,POSIXの標準,すなわち「POSIX Part2:Shell and Utilities」として標準化されています。
しかし,さまざまなエディタ,プログラミング言語,シェルは,かならずしもPOSIX標準で定められた表現をすべては実装していません。さらに独自に拡張した正規表現も含めています。従って基本的な正規表現を覚えたら,用途に応じて「方言」に習熟する必要があります。
...

...
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
katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2015/04/18 17:19

ご回答有難うございます。 参考ページの提示、引用をありがとうございます。 これらを参考に勉強させていただきます。 皆様大変参考になるご投稿を頂いております。 ベストアンサーにどなたを選ぶのかを悩みましたが「+」の数の多いkatoy様にさせていただきます。 ありがとうございました。
guest

0

正規表現には、取り除いたりする機能はありません。「取り除く」等は正規表現を使うプログラミング言語側の機能です。

正規表現は、「文字列の中の一部」を指定する方法です。文字列の一部を指定する場合に、「123文字目から200文字目」などのように文字数位置で指定する方法もありますが、そうではなく、「"A"という文字から"B"という文字が出てくるまで」とか「3桁の数字」というように文字列の内容で文字列の一部を指定する方法です。

例えば/[A-Z]/だと、「半角英字の大文字1文字」という一部分を指定します。その一部分を削除するのか、取り出すのか、置き換えるのか、などは正規表現で無く、それを使うプログラミング言語側で処理します。

正規表現は、あくまで、「文字列のどの場所なのか」を指定する機能です。

投稿2015/02/28 08:52

otn

総合スコア84557

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t_smz

2015/04/06 00:46

この方の回答が一番しっくりきます。 正規表現自体がいろいろと拡張をされているがために複雑に見えますが、 もともとは数学の概念です。 集合論から派生したオートマトン理論から生まれたものです。 あるルールの集合を正確に記述するために編み出された表記法です。 ですので、対象を文字列に限ったものではありません。 ある文字列がその集合に含まれるかどうかの判断までが正規表現の機能です。 それ以外の機能(例えば文字列の置換や文字列の一部抽出など)は 文字列処理ライブラリが正規表現という便利な技法を応用しているに過ぎません。
nnahito

2015/04/18 17:24

ご回答有難うございます。 内容的な解説、大変参考になります。 /[A-Z]/、perlなどでよく見かけます。 今やっと意味がわかりました。 ベストアンサーにどなたを選ぶのかを悩みましたが「+」の数の多い方にさせていただきます。 ありがとうございました。
guest

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
munyaX

総合スコア783

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2015/04/18 17:22

ご回答有難うございます。 サンプルや、「一言で言うと」など、ひと目で分かりやすい解説をありがとうございます。 ベストアンサーにどなたを選ぶのかを悩みましたが「+」の数の多い方にさせていただきます。 ありがとうございました。
guest

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
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2015/04/18 17:26

ご回答有難うございます。 ご提示頂きました、参考書に少し興味を持ちましたので、研究室の経費で購入させていただこうと思います(笑) ありがとうございます。 ベストアンサーにどなたを選ぶのかを悩みましたが「+」の数の多い方にさせていただきます。 ありがとうございました。
guest

0

/[0-9.‐-]/g
この[]の中の 0-9の-は0から9なのですから
.‐-も素直に、 .から- の意味です 取り除くの意味はありませんし
半角-は合致しません

難しいと思ったのも実は勘違いしているだけかもしれませんよ。

投稿2015/03/03 04:47

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2015/04/18 17:29

ご回答有難うございます。 難しいと思っているのは勘違い……かも知れませんが、それでも少し難しいです。 なんせ慣れていない表現でかつ、言語に寄って若干表記が異なるらしいので…… ベストアンサーにどなたを選ぶのかを悩みましたが「+」の数の多い方にさせていただきます。 ありがとうございました。
guest

0

[]の間にある-と、普通の-は意味が違うんで、
囲われたものと囲われてないものの違いを覚えるだけでダイジョブです。
^は先頭を意味しますが、[]の中では、除外の意味なります。

投稿2015/03/03 05:47

Seiji_Ogawa

総合スコア112

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2015/04/18 17:29

ご回答有難うございます。 覚えるコツを短くまとめていただきありがとうございます。 参考にさせていただきます。 ベストアンサーにどなたを選ぶのかを悩みましたが「+」の数の多い方にさせていただきます。 ありがとうございました。
guest

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
sho_cs

総合スコア3541

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2015/04/18 17:16

ご回答有難うございます。 詳しいご回答有難うございます。 置換の件に関しては私の完全なる勘違いです。 申し訳ありません。
nnahito

2015/04/18 17:22

大変参考になるご投稿をありがとうございます。 ベストアンサーにどなたを選ぶのかを悩みましたが「+」の数の多い方にさせていただきます。 ありがとうございました。
guest

0

「正規表現」は、規則のある文字列を探したり置き換えたりする表現方法で、プログラムの中で使われますが、どのプログラム言語の「正規表現」も似ていますが、同じではありません。
「正規」という言葉から「普遍的に正しい」みたいな意味を感じますが、結局、言語毎に正規表現があってそれを覚える必要が出てきます。なので理解をする事は時間と努力の無駄、正規表現事例集を見ながら書けば十分だと考えます。
「正規」なんて幻想だと思いますよ。

投稿2015/03/01 12:19

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katoy

2015/03/01 14:06

> ... 理解をする事は時間と努力の無駄 ... そんなことはないとおもいます。 正規表現 の基本的な概念は重要なものです。 基本概念を理解する事に時間を割く事は無駄にはなりません。 言語毎の正規表現の機能・表記の差は方言のようなものであり、 基本が理解できていれば言語毎の差も理解しやすくなります。
maisumakun

2015/03/02 01:53

「正規表現」というのはもともと数学的な概念で、「特定の構造で生成される文法を持った言語」としての意味合いがありますので、使う側での混乱とは本質的に無縁な名前です。 もっとも、(前方でキャプチャしたものを後方から参照する場合などが典型的ですが)拡張された結果、数学的な意味合いでの正規表現の範疇をはみ出してしまっている事例もあります。
munyaX

2015/03/03 04:02

全然関係ないですが、スコアってマイナスになるんですねw > 理解をする事は時間と努力の無駄 シェルでコマンド叩くときに、毎回本を開くのめんどいですw
hpfoon

2015/03/03 09:09

ぱっと見が呪文みたいで直感的に分かりずらいのと、「正規」という言葉があたかも「正しいひとつのものがある」みたいな印象を与えるのが混乱の元なのですかね。 自分だと、正規化って、一定の幅に収めるみたいなイメージがありますが。(英語だとModulationかな) 処理系によって動作が微妙に異なるのは嫌ですね。言葉のイメージだけで話が進んでしまうような不幸が発生しない事を祈ります。
munyaX

2015/03/03 09:13

元々の英語が「Regular expression」なので、その直訳なんですよね。 この議論は以前よく見かけましたw
nnahito

2015/04/18 17:27

ご回答有難うございます。 確かに、私も「覚える」という行為は苦手ですので、基本的に書籍や参考サイト様などを見ながら書くことが多いです。 慣れてくると、手が勝手に動くのでそこからは必要ありませんが…… しかし、内容について、もう少々詳しく解説を頂きたいかなと思いました。
guest

0

こんにちは。

以前、このご質問の回答に

ある条件を満たす文字列の集合(を 、文字列で表現したもの)

と書かせて頂きましたが、このような捉え方で、より詳しく説明している文章を
超絶スゴいハッカーが創設者のプロジェクト内に、)みつけたので参考のため
追記させて頂きます。

  1. GNU プロジェクトホームページに行く。

  2. 画面上の「ソフトウェア」をクリックして、GNUソフトウェアのページに行く。

  3. 画面下のほうに様々なソフトウェアのリンクのうち「退役したGNUパッケージ」にある、

  regex をクリック

  1. 説明に

… see also the Regular expressions chapter in the Gnulib manual, …

とあるのに従って、gnulib の正規表現の章に行く。

  1. Overview をクリック

  2. 冒頭に以下のように書かれています。


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
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問