0

私は現在持っています:

(Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday),?\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+[0-3]?[0-9],?\s+[0-2][0-9][0-9][0-9],?\s+([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-9][0-9][0-9],?\s+(AM|PM)

...私の正規表現としてですが、小さなテスト ハーネスを使用してアサートすると、失敗することがわかりました。どこがめちゃくちゃなの?Web アプリから日時テキストを取得し、正規表現の上に一致すると主張しています。

4

4 に答える 4

6

ジョブに不適切なツール

正規表現を修正しようとしている他のすべての回答は、間違った正規表現の別の部分に関するものです。これは、それが仕事に適したツールではないことを示しているはずです。

正規表現が短くてコンパクトな場合、正規表現を正しく理解するのは困難です。この長さの 1 つを正しく理解するのは悪夢であり、不可解な方法で壊れることを恐れて、将来誰もそれに触れることができなくなります。

慣用的なJava

SimpleDateFormat.parse()StringJavaでフォーマットされた日付情報を処理する慣用的な方法です。

正規表現はマッチング用

問題に直面したときに、「分かった、正規表現を使用する」と考える人もいます。現在、彼らには 2 つの問題があります - Jamie Zawinski

そして、その引用alt.religion.emacsメーリングリストからのものです!

SimpleDateFormat.parse()なぜ正しいことをするのかを説明するための不十分な解決策。

いずれにせよ、正規表現で必要なものを一致させることはできますが、実行しようとしているすべての検証を行うべきではありません。検証ロジックと一致するロジックを混同しています。2つは一部の領域で重複しているように見えますが、この場合、検証は正規表現テストではなくコードである必要があります。

(Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday), (January|February|March|April|May|June|July|August|September|October|November|December) (\d{2}), (\d{4}) (\d{1,2}):(\d{2}):(\d{2})\.(\d{3}) (AM|PM)

上記の式は、タイトルで要求された文字列と一致します。しかし、数値の範囲を検証しようとはしません。検証した場合、うるう年と 2 月についてどうするつもりですか? 、正規表現は維持するのがさらに悪くなります。

このような場合、正規表現を使用してデータのトリアージを行い、パターンまたはフォーマットに一致することを確認してから、それを実際のパーサーに渡すか、グループを実際に範囲検証を行うメソッドに渡す必要があります。他のもの。

于 2012-08-09T17:01:02.213 に答える
0

:秒を省略し、正規表現ではミリ秒にa を使用してい.ますが、質問のタイトルの例では a を使用しています。だから試してみてください:

(Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday),?\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+[0-3]?[0-9],?\s+[0-2][0-9][0-9][0-9],?\s+([01]??[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9].[0-9][0-9][0-9],?\s+(AM|PM)
于 2012-08-09T17:00:26.160 に答える
0

正規表現は日付を解析するための最良のツールではないかもしれませんが、あなたの正規表現で際立っているのはここだけです。

あなたの時間は秒に3桁が必要なようで、ミリ秒は含まれていません:

([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-9][0-9][0-9]

次のように変更してみてください。

([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-9]{2}\.[0-9]{3}

[0-9]一部の文字を保存したい\d場合は、すべてを変更することもできます。

于 2012-08-09T16:58:32.773 に答える
0

正規表現がこの仕事に適していないという以前のスピーカーには同意しますが、正確な日付と一致する自動生成されたスニペットを次に示します。

import java.util.regex.*;

class Main
{
  public static void main(String[] args)
  {
    String txt="Wednesday, August 08, 2012 9:38:31.113 AM";

    String re1="((?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday|Tues|Thur|Thurs|Sun|Mon|Tue|Wed|Thu|Fri|Sat))";    // Day Of Week 1
    String re2=".*?";   // Non-greedy match on filler
    String re3="((?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Sept|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?))";   // Month 1
    String re4=".*?";   // Non-greedy match on filler
    String re5="((?:(?:[0-2]?\\d{1})|(?:[3][01]{1})))(?![\\d])";    // Day 1
    String re6=".*?";   // Non-greedy match on filler
    String re7="((?:(?:[1]{1}\\d{1}\\d{1}\\d{1})|(?:[2]{1}\\d{3})))(?![\\d])";  // Year 1
    String re8=".*?";   // Non-greedy match on filler
    String re9="(\\d+)";    // Integer Number 1
    String re10=".*?";  // Non-greedy match on filler
    String re11="(\\d+)";   // Integer Number 2
    String re12=".*?";  // Non-greedy match on filler
    String re13="(\\d+)";   // Integer Number 3
    String re14=".*?";  // Non-greedy match on filler
    String re15="(\\d+)";   // Integer Number 4
    String re16=".*?";  // Non-greedy match on filler
    String re17="((?:[a-z][a-z]+))";    // Word 1

    Pattern p = Pattern.compile(re1+re2+re3+re4+re5+re6+re7+re8+re9+re10+re11+re12+re13+re14+re15+re16+re17,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    Matcher m = p.matcher(txt);
    if (m.find())
    {
        String dayofweek1=m.group(1);
        String month1=m.group(2);
        String day1=m.group(3);
        String year1=m.group(4);
        String int1=m.group(5);
        String int2=m.group(6);
        String int3=m.group(7);
        String int4=m.group(8);
        String word1=m.group(9);
        System.out.print("("+dayofweek1.toString()+")"+"("+month1.toString()+")"+"("+day1.toString()+")"+"("+year1.toString()+")"+"("+int1.toString()+")"+"("+int2.toString()+")"+"("+int3.toString()+")"+"("+int4.toString()+")"+"("+word1.toString()+")"+"\n");
    }
  }
}

何があっても恐ろしい正規表現が必要な場合は、ネット上で素晴らしいツールを利用できます: http://txt2re.com/

于 2012-08-09T17:23:18.480 に答える