正規表現 Part7

このエントリーをはてなブックマークに追加
932デフォルトの名無しさん:2011/03/02(水) 15:45:24.49
お知恵をお貸しください…!どうかお詳しい方よろしくお願いいたしますm(__)m

●正規表現の使用環境
VBScript

●検索か置換か?
検索

●説明
メールアドレスをチェックしたい
1.メールは1つか、複数
2.複数メールはカンマで区切られる
3.カンマの直後にスペースが入るかも
4.メールの@以降は固定(間違って変な宛先に送らないため)
5.@より前はてきとう

つづく
933デフォルトの名無しさん:2011/03/02(水) 15:45:37.70
つづき

●対象データ
[email protected] ←1つだけの場合
[email protected], [email protected], ...(以下、繰り返し) ←複数の場合


●希望する結果
True または False

●↓ここまでやって力尽きました。。orz
Function blnMailCheck(strMailAddress)
  Dim objRE
  Set objRE = new RegExp
  objRE.IgnoreCase = True
  '以下のパターンが今回質問したいところです
  'イメージとしては、メールが1回以上、各メール間に「,」を1つと直後にスペースを0回以上出現
  objRE.pattern = "^(.*@example.com),+$"
  blnMailCheck = objRE.Test(strMailAddress)
  Set objRE = Nothing
End Function
934デフォルトの名無しさん:2011/03/02(水) 17:41:31.90
>>932-933
・何をどこまでチェックしたいのか
・使用できる文字の範囲
によって変わってくると思うけど、なるべく単純にするとこんな感じ?
^([-.a-z0-9][email protected], *)*[-.a-z0-9][email protected]$

>5.@より前はてきとう
適当バージョン
^([^ @][email protected], *)*[^ @][email protected]$
935デフォルトの名無しさん:2011/03/02(水) 17:58:18.42
ありがとうございます。いただいたパターンを試してみます。

・何をどこまでチェックしたいのか

たとえば、以下のようにメールアドレスが入力された場合は、
個々のメールの@以下がすべて、「@example.com」であれば
Trueである、としたいです。

[email protected], [email protected]

しかし、実際はメールが1つしか入力されない場合や、
カンマの直後にスペースがあったりなかったりします。

・使用できる文字の範囲

@より前はなんでもいいです。(送信に失敗するだけなので)
@以降は、「@example.com」固定にしたいです。

よろしくお願いいたします。
936デフォルトの名無しさん:2011/03/02(水) 18:09:29.61
>>934

すみません、そのパターンは2つとも、
「-1」という結果が返ってきてしまいました。

引数は「[email protected]」のみです。

もう一度、明日確認してみます。m(__)m
937デフォルトの名無しさん:2011/03/02(水) 18:19:56.83
>>936
お前さんは何か勘違いしている
正規表現の前にvbsの使い方を覚えるぺき
938932:2011/03/02(水) 18:50:51.25
>>937

パターンを「.*」のようにすればtrueが返ってくるので、
あとは適切なパターンを指定してあげるだけかと思ったのですが…

「文字列がメールアドレスかどうか判定する」
という正規表現ならググるといくつかヒットするので、
私のやりたいこともできるかも?と思った次第です。
この考え方がそもそも間違っているのでしょうか?(/ _ ; )

もしよろしければ、どこらへんを勘違いしてるかを
指摘していただけると、とてもとても助かりますm(_ _)m
939934:2011/03/02(水) 18:56:16.94
>>936>>938
えーと、あなたのサンプルプログラムに>>934で挙げた正規表現をはめ込み、
MsgBox blnMailCheck("[email protected]")
みたいにしたら、Trueと出たけど?

VBScriptのリファレンスで、Regular Expression オブジェクトのTest メソッドを見ても、
>Test メソッドは、パターンに一致する文字列が見つかると True、見つからないと False を返します。
となってるし??
私にはこれ以上分かりませぬ。

一応…適当バージョンで@より前位置のカンマも不可ならこんな感じ。
^([^ ,@][email protected], *)*[^ ,@][email protected]$
940932:2011/03/02(水) 19:33:16.76
>>939

なるほど!!
呼び出し元がおかしいってことですね。
丁寧な説明、リファレンスまで調べていただき、
大変なお手間を取らせてしまいごめんなさい。
おっしゃる通りVBScriptはまだまだ経験が浅いです(>_<)
今回のことをきっかけにして頑張っていきたいと思います。
今回は本当に勉強になりました。
どうもありがとうございました!
941デフォルトの名無しさん:2011/03/02(水) 21:57:15.32
>>932
vbsで-1はTrueだ
覚えておくように
942デフォルトの名無しさん:2011/03/02(水) 23:26:48.73
単に,でSplitしてFor Eachで@example.com$チェックしていけば十分だと思うけど
それにしてもVBSってLike演算子ないのか
943932:2011/03/03(木) 06:04:41.74
>>941
!?(・_・;? -1はFalseだとばかり思い込んでました…
ご指摘ありがとうございます!

>>942
そんな方法もいけるんですね
もっと発想を柔らかくしないとなぁ
ご意見ありがとうございます(^-^)/
944934:2011/03/03(木) 06:29:13.17
>>943
すまん、ドットに\を付け忘れてたことに気付いた。
^([^ ,@]+@example\.com, *)*[^ ,@]+@example\.com$
ついでに…
どうやって-1を目撃したのか見当つかないけど、以下は読んでおいてね。
VBScript ユーザーズ ガイド - VBScript の基本 - VBScript のデータ型
945932:2011/03/03(木) 12:27:23.67
>>944
WScript.Echo blnMailCheck(strMailAddress)
↑で結果を確認してました…
素直にIf を使っていれば良かったorz
教えていただいたサイトをじっくり読んでみます!
ありがとうございました(^-^)/
946デフォルトの名無しさん:2011/03/04(金) 16:59:16.71
16進数を2桁づつに分解する正規表現って
例えば
'5d8ce34a7dbaab'

['5d', '8c', 'e3', '4a', '7d', 'ba', 'ab']
というリストにしたい場合
([0-9A-Fa-f]{2}){7}
じゃだめなんでしょうか?
947デフォルトの名無しさん:2011/03/04(金) 19:13:56.93
>>946
分解してないじゃん
948デフォルトの名無しさん:2011/03/04(金) 19:36:45.66
正規表現は文字列にマッチするかしないかだけだよ
リストに分割するとかそんな機能は持ってない

Pythonだったら
import re
re.findall(r'[0-9a-fA-F]{2}', '5d8ce34a7dbaab')

Rubyだったら
'5d8ce34a7dbaab'.scan(/[0-9a-fA-F]{2}/)
949946:2011/03/04(金) 21:39:54.16
>>947-948
ありがとうございます
wxRegEx を使っています

wxRegEx re("([0-9a-fA-F]{2}){7}", wxRE_ADVANCED | wxRE_ICASE);
re.Matches(str);
とやっても
re.GetMatchCount()
の数が変なんです

wxRegEx re("([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})", wxRE_ADVANCED | wxRE_ICASE);
re.Matches(str);
なら
re.GetMatchCount() == 7
になるみたいなのですが
そんなもんなんでしょうか?
950デフォルトの名無しさん:2011/03/04(金) 21:41:05.83
すみません
re.GetMatchCount() == 8
の間違いです
951デフォルトの名無しさん:2011/03/04(金) 21:48:02.43
wxRegExとか知らんけど、
[0-9a-fA-F] は [0-9a-f] にして i オプション使ったほうが見やすいと思う
952デフォルトの名無しさん:2011/03/04(金) 21:48:08.48
どこがおかしいんだ?
953デフォルトの名無しさん:2011/03/04(金) 22:11:16.32
>>949
http://docs.wxwidgets.org/stable/wx_wxregex.html#wxregexmatches

最低限のメソッドしかないみたいだから自前でループで回すしかないだろう
[0-9a-fA-F]{2}を文字列にマッチさせる
マッチした分だけ文字列へのポインタを先に進める
くりかえし
954デフォルトの名無しさん:2011/03/04(金) 22:30:48.27
>>953
ありがとうございます
思い違いをしていたみたいです
ループは自分でやらないといけないんですね
955デフォルトの名無しさん:2011/03/04(金) 23:17:30.13
>>953
これでうまくいったみたいです
ほんとうにありがとうございました

wxArrayString FindAll(const wxRegEx &re, const wxString &str)
{
  wxArrayString as;
  for(wxString s = str; re.Matches(s); s = s.Mid(re.GetMatch(s, 0).length()))
    for(size_t i = 1; i < re.GetMatchCount(); i++)
      as.Add(re.GetMatch(s, i));
  return as;
}

ちなみに exe ファイルのサイズは FindAll を使う前に比べて 512 バイト増えました
速度差は調べていません
956デフォルトの名無しさん:2011/03/05(土) 00:36:13.62
そりゃ3行程度で済む内容をいちいち関数呼んでたらサイズも大きくなるし速度も遅くなるだろうな
957デフォルトの名無しさん:2011/03/05(土) 00:45:20.51
>>956
スレ間違えてるぞ
958デフォルトの名無しさん:2011/03/05(土) 09:58:12.85
XXXとYYYの間を削除したくて、
javaで、replaceAll("XXX.*YYY", "")
このようなコードを書いてるんですが、対象が複数ある場合にうまくいきません。

AAAXXXBBBYYYCCCXXXDDDYYYEEE
AAACCCEEE ←このように変換したい 
AAAEEE ←こうなってしまう

最初のXXXと最後のYYYで認識されてしまってるようなんですが、どのようにすればよいでしょうか
959デフォルトの名無しさん:2011/03/05(土) 10:11:33.97
>>958
すみません。自己解決しました。
960デフォルトの名無しさん:2011/03/05(土) 16:30:42.26
欲張り、無欲に関する質問は定期的にあるのな
961デフォルトの名無しさん:2011/03/05(土) 17:47:01.88
強欲(possessive)というのもあるよね
962デフォルトの名無しさん:2011/03/06(日) 08:59:14.88
おまえらにぴったりな言葉だな
963デフォルトの名無しさん:2011/03/06(日) 13:42:42.28
まぁ過去を振り返ってもしょうがないしな
964デフォルトの名無しさん:2011/03/06(日) 14:08:17.33
過去は振り返るものじゃない
しがみつくものだ
965デフォルトの名無しさん:2011/03/06(日) 14:52:12.70
過去を振り返ることができるからずっと先に向かって歩いていけるのさ
966デフォルトの名無しさん:2011/03/07(月) 22:00:02.04
ギップルさん召喚の儀式か?
967デフォルトの名無しさん:2011/03/11(金) 08:15:56.22
過去こそが眼前にあるものであって、背後にあるものは未来である
968デフォルトの名無しさん:2011/03/14(月) 19:06:44.98
●正規表現の使用環境
Perl

●検索か置換か?
置換

●説明
重複する文字列と区切り文字を削除したい

●対象データ
aaa;bbb;ccc;bbb;あああ;aaa;あああ;いいい

●希望する結果
aaa;bbb;ccc;あああ;いいい

よろしくお願いします
969デフォルトの名無しさん:2011/03/14(月) 19:20:50.55
区切りごとに分割して、ソートで重複を除く
970デフォルトの名無しさん:2011/03/14(月) 19:27:38.40
uniqもねーのかこの言語
my $a = 'aaa;bbb;ccc;bbb;あああ;aaa;あああ;いいい';
my %a;
$a =~s/([^;]+);?/$a{$1}++==0?$&:''/ego;
971デフォルトの名無しさん:2011/03/14(月) 19:45:47.43
>>968
区切り文字が削除されていない。
972デフォルトの名無しさん:2011/03/14(月) 20:54:16.83
>>969-970
ありがとうございます
やってみます
>>971
説明が間違ってました
●希望する結果のほうであってます
973デフォルトの名無しさん:2011/03/15(火) 12:10:55.80
正規表現にこだわらなければ、>>969-970の合わせ技も

my $s = "aaa;bbb;ccc;bbb;あああ;aaa;あああ;いいい";
my %seen;
$s = join ";", grep { !$seen{$_}++ } split /;/, $s;
974デフォルトの名無しさん:2011/03/15(火) 15:15:44.19
●正規表現の使用環境
linux コマンドラインの grep

●検索か置換か?
検索

●説明
末尾が一致していて途中が違う文字列のうち、特定のパターンを除去した集合を取得したい

●対象データ
aaabbbcccあああいいい
aaabbbcccううういいい
aaabbbcccえええいいい

●希望する結果
aaabbbcccううういいい
aaabbbcccえええいいい

「説明」がうまく書けないのですが。
よろしくお願いします
975デフォルトの名無しさん:2011/03/15(火) 15:23:30.71
grep 'いいい$' | grep -v 'あああ'
976974:2011/03/15(火) 15:38:21.24
なるほど。
助かりました。ありがとう。
977デフォルトの名無しさん:2011/03/15(火) 17:34:57.18
>>968
これと同じ事をBREGEXP DLLを使った正規表現置換でやりたいのですが可能でしょうか?
978デフォルトの名無しさん:2011/03/19(土) 19:03:20.06
>>977
>>970>>973もマッチだけでは完結してない
つまり正規表現を使う何らかのプログラミング言語のコードが必要
979デフォルトの名無しさん:2011/03/22(火) 23:58:13.69
tes
980デフォルトの名無しさん:2011/03/23(水) 00:02:06.70
ファイルから読んだ文字列の中に正規表現があるとして
それを展開して処理することはできますか?

$moji = "123";
$hoge = "12\d";
if($moji =~ /$hoge/){
  print "一致";
981デフォルトの名無しさん
正規表現の文字列があった場合にTRUEなのね。
危険だと思う。