Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Peal -> PERL に修正

Excerpt
hiddentrue

Regular Expressions

正規表現

Excerpt
hiddentrue

Regular expressions are the Swiss Army knife of text processing. They provide the programmer the ability to match and extract *patterns* from strings. The simplest example of a regular expression is a string of letters and numbers. And the simplest expression involving a regular expression uses the *==~* operator. So for example to match Dan Quayle's spelling of 'potato':

正規表現は、テキスト処理のスイス軍用万能ナイフです。 プログラマーは文字列をパターンでマッチさせ、さらにマッチしたものを、取り出す事ができるようになります。 正規表現の一番シンプルな例は、 文字や数字と==~オペレーターを使ったものです。 では、Dan Qualye氏のポテトのスペル'potatoe'でマッチを試してみましょう。(訳注:ダン・クエール Dan Qualye 1989年~93年 ブッシュ大統領の下で副大統領を務める。ポテトのミススペル potatoe で有名になったらしい。 正しいスペルは、potato です)

Code Block

"potatoe" ==~ /potatoe/     ===> true

Excerpt
hiddentrue

If you put that in the groovyConsole and run it, it will evaluate to true. There are a couple of things to notice. First is the == ~ operator, which is similar to the == operator, but matches patterns instead of computing exact equality. Second is that the regular expression is enclosed in /'s. This tells groovy (and also anyone else reading your code) that this is a regular expression and not just a string.
But let's say that we also wanted to match the correct spelling, we could add a '?' after the 'e' to say that the e is optional. The following will still evaluate to true.

groovyコンソールで実行すると true と評価されます。注目点は、第1に==~オペレーターです。==オペレーターと似ていますが、equality の検査でなく、パターンマッチを行います。第2に正規表現が / に囲まれていることです。 / の囲みが groovy とコードの読み手にこの中は、単なる文字列でなく正規表現であることを伝えます。
正しいスペル potato もマッチさせたい場合は、'e'の後ろに'?'を付けます。以下は、依然として true と評価され:

Code Block

"potatoe" ==~ /potatoe?/     ===> true

Excerpt
hiddentrue

And the correct spelling will also match:

正しいスペルもマッチします: 

Code Block

"potato" ==~ /potatoe?/     ===> true

Excerpt
hiddentrue

But anything else will not match:

でも、その他では、マッチしません:

Code Block

"motato" ==~ /potatoe?/    ===> false

Excerpt
hiddentrue

So this is how you define a simple boolean expression involving a regular expression. But let's get a little bit more tricky. Let's define a method that tests a regular expression. So for example, let's write some code to match Pete Wisniewski's last name:

マッチしたかbooleanを返す簡単な正規表現でした。 
もう少し進みましょう。 正規表現をテストするメソッドを書いてみましょう。 Pete Wisniewski  という名前の ラストネーム Wisniewski でマッチさせるサンプルです。 (訳注:Pete Wisniewski が何者か不明)

Code Block

def checkSpelling(spellingAttempt, spellingRegularExpression)
{
  if (spellingAttempt ==~ spellingRegularExpression)
  {                println("Congratulations, you spelled it correctly.")          }
  else
  {                println("Sorry, try again.")         }
}
theRegularExpression = /Wisniewski/
checkSpelling("Wisniewski", theRegularExpression)
checkSpelling("Wisnewski", theRegularExpression)

Excerpt
hiddentrue

There are a couple of new things we have done here. First is that we have defined a function (actually a method, but I'll use the two words interchangably). A function is a collection of code similar to a closure. Functions always have names, whereas closures can be "anonymous". Once we define this function we can use it over and over later.

In this function the *if* statement in bold tests to see if the parameter spellingAttempt matches the regular expression given to the function by using the *==~* operator.

Now let's get a little bit more tricky. Let's say we also want to match the string if the name does not have the 'w' in the middle, we might:

新しい事が出てきました。 関数(function)です。(正確にはメソッドですが、私はこの2つの言葉を同じように使っています) 関数は、クロージャーに似た、コードの集まりです。 関数は常に名前があります。 一方はクロージャーには無名(anonymous)も可能です。 関数を定義すると後で何回でも使うことができます。
この関数の青地の if ステートメントでは、パラメーターのスペルをチェックしたい文字列と同じくパラメーターの正規表現がマッチするするか ==~ オペレーターでテストします。
さらに進みましょう。 文字列の真ん中の 'w' 文字がなくてもマッチしたい時:

Code Block

theRegularExpression = /Wisniew?ski/
checkSpelling("Wisniewski", theRegularExpression)
checkSpelling("Wisnieski", theRegularExpression)
checkSpelling("Wisniewewski", theRegularExpression)

Excerpt
hiddentrue

The single *?* that was added to the spellingRegularExpression says that the item directly before it (the character 'w') is optional. Try running this code with different spellings in the variable *spellingAttempt* to prove to yourself that the only two spellings accepted are now "Wisniewski" and "Wisnieski". (Note that you'll have to leave the definition of checkSpelling at the top of your groovyConsole)

The *?
* is one of the characters that have special meaning in the world of regular expressions. You should probably assume that any punctuation has special meaning.

Now let's also make it accept the spelling if "ie" in the middle is transposed. Consider the following:

スペルチェックの正規表現に追加された1個の ? は  その直前の要素(ここでは 'w' 文字)が任意(あるか、ないかのどちらか)である事を現します。 変数 spellingAttempt に色々なスペルを入れて試してみましょう。 2つのスペルのみ通ることが分かります。 'Wisniewski' と 'Wisnieski' です。 (注:groovyコンソールの最初にcheckSpellingの定義を残しておいてくださいね)
この '?' は正規表現の世界で特別の意味をもった文字の一つです。
次に、チェック対象スペルの真ん中にある 'ie' という文字が逆順でも通るようにしてみます。 次のコードを見てみてください:

Code Block

theRegularExpression = /Wisn(ie|ei)w?ski/
checkSpelling("Wisniewski", theRegularExpression)
checkSpelling("Wisneiwski", theRegularExpression)
checkSpelling("Wisnieski", theRegularExpression)
checkSpelling("Wisneiski", theRegularExpression)

checkSpelling("Wisniewski", theRegularExpression)
checkSpelling("Wisneiwski", theRegularExpression)

Excerpt
hiddentrue

Once again, play around with the spelling. There should be only four spellings that work, "Wisniewski", "Wisneiwski", "Wisnieski" and "Wisneiski". The bar character '|' says that either the thing to the left or the thing to the right is acceptable, in this case "ie" or "ei". The parentheses are simply there to mark the beginning and end of the interesting section.

One last interesting feature is the ability to specify a group of characters all of which are ok. This is done using square brackets *[ ]*. Try the following regular expressions with various misspellings of Pete's last name:

"Wisniewski", "Wisneiwski", "Wisnieski",  "Wisneiski" の4つのスペルだけマッチします。 '|' 記号は、左側または右側のどちらかのみを許可します。ここでは "ie" または "ei" です。( ) かっこは、適用範囲を示します。
最後に紹介するおもしろい機能は、「キャラクタ(1文字)の集まりの中のどれかのキャラクタ(1文字)とマッチするかチェックする」です。 [ ] かっこを使います。 Peter さんのラストネームの色々な間違ったスペルでこの正規表現を試してみましょう。
Excerpt
hiddentrue

theRegularExpression = /Wis[abcd]niewski/ // requires one of 'a', 'b', 'c' or 'd'
theRegularExpression = /Wis[abcd]?niewski/ // will allow one of 'a', 'b', 'c' or 'd', but not required (like above)
theRegularExpression = /Wis[a-zA-Z]niewski/ // requires one of any upper
- or lower-case letter
theRegularExpression = /Wis[^abcd]niewski/ // requires one of any character that is '''not''' 'a', 'b', 'c' or 'd'

Code Block

theRegularExpression = /Wis\[abcd\]niewski/ // 'a', 'b', 'c', 'd' のどれか一つがあること
theRegularExpression = /Wis\[abcd\]?niewski/ // 'a', 'b', 'c', 'd',  のどれか一つがあること または、 何もないこと
theRegularExpression = /Wis\[a-zA-Z\]niewski/ // アルファベットの小文字または大文字のどれか一文字があること
theRegularExpression = /Wis\[^abcd\]niewski/ // 'a', 'b', 'c', 'd' 以外のなにか一つのキャラクタがあること

Excerpt
hiddentrue

The last one warrants some explanation. If the first character in the square brackets is a *^
* then it means anything but the characters specified in the brackets.

最後の行は、説明が要りますね。 かぎかっこ [ ] 内の最初の文字は ^ ですが、これは、かっこ内の文字以外の一つの文字を現します。
Excerpt
hiddentrue

The operators

オペレーター

Excerpt
hiddentrue

So now that you have a sense for how regular expressions work, here are the operators that you will find helpful, and what they do:

ここまでで、正規表現がどう働くのかの感じがつかめたね。 以下はよく使う正規表現オペレターです。
Excerpt
hiddentrue

Regular Expression Operators

 正規表現オペレーター

Excerpt
hiddentrue

a?

matches 0 or 1 occurrence of *a*

'a' or empty string

a*

matches 0 or more occurrences of *a*

empty string or 'a', 'aa', 'aaa', etc

a+

matches 1 or more occurrences of *a*

'a', 'aa', 'aaa', etc

a|b

match *a* or *b*

'a' or 'b' -

.

match any single character

'a', 'q', 'l', '_', '+', etc

[woeirjsd]

match any of the named characters

'w', 'o', 'e', 'i', 'r', 'j', 's', 'd'

[1-9]

match any of the characters in the range

'1', '2', '3', '4', '5', '6', '7', '8', '9'

[^13579]

match any characters not named

even digits, or any other character

(ie)

group an expression (for use with other operators)

'ie'

^a

match an *a* at the beginning of a line

'a'

a$

match an *a* at the end of a line

'a'

There are a couple of other things you should know. If you want to use one of the operators above to mean the actual character, like you want to match a question mark, you need to put a '\' in front of it. For example:

...

覚えておく事。 上記のオペレーターをただのキャラクタとして扱いたい時(たとえば、クエッションマークをマッチしたい)は、前に'\'をおく必要があります。 例:

Code Block

// evaluates to true, and will for anything ending in a question mark (that doesn't have a question mark in it)
"How tall is Angelina Jolie?" ==~ /[^\?]+\?/

Excerpt
hiddentrue

This is your first really ugly regular expression. (The frequent use of these in PERL is one of the reasons it is considered a "write only" language). By the way, google knows how tall [she is|http://www.google.com/search?hl=en&q=how+tall+is+angelina+jolie&btnG=Google+Search]. The only way to understand expressions like this is to pick it apart:|| / || [^?] || + || ? || / |||| begin expression || any character other than '?' || more than one of those || a question mark || end expression || So the use of the \ in front of the ? makes it refer to an actual question mark. ||

これは、醜い正規表現ですね。(Pealでの、このようなコードの多用が、Pealが書くためだけの言語といわれる理由の一つです)
これは、醜い正規表現ですね。(PERLでの、このようなコードの多用が、PERLが書くためだけの言語といわれる理由の一つです)
   ところでアンジョリーナ・ジョリーの身長は、googleで分かりますよ[she is|http://www.google.com/search?hl=en&q=how+tall+is+angelina+jolie&btnG=Google+Search]

このような正規表現の理解の仕方は、ばらばらにして見ることです。

/

[^?]

+

?

/

正規表現の始まり

'?' 以外のキャラクタ

1回以上の繰り返し

クエッションマーク文字

正規表現の終わり

...