2

文を取得して特定のボックスをチェックしたり、テキスト入力に数字を入力したりする必要がある状況があります。

ボックスは次のようなものです..

  • 毎日
  • 毎週
  • 毎月

したがって、さまざまな正規表現オブジェクトを使用してさまざまな状況を検索する方が良いかどうか、または 1 つの大きな正規表現オブジェクトを作成してから結果を切り替え/大文字小文字を区別する必要があるかどうかはわかりません。

文字列の例を次に示します。

  • 毎日
  • 平日毎日
  • 毎週日曜日、月曜日、水曜日
  • 3週間ごとの日曜日、金曜日
  • 毎月第一日曜日
  • 2 か月ごとの 1 日
  • 毎年1月1日

正規表現に関しては問題ありませんが、これは的外れであり、別の正規表現オブジェクトを使用するべきか、大きなオブジェクトを作成しようとするべきかわかりません。助けてくれてありがとう

/\w+\s?(\d+?)?\s(\w+)/ は、「毎週」、「毎日」、「毎月」、「毎年」、「10 日ごと」を処理するようです。など

4

2 に答える 2

3

ここでは、正規表現があまり役に立たないと思います。彼らは本当に単純な照合をいくつか行うことができるかもしれませんが、ここで実際に見ているのは文法解析の問題です. Extended Backus-Naur Form (EBNF)など、抽象文法を表現するように設計された言語について読みたいと思うかもしれません。威圧的に聞こえるかもしれませんが、理解するのはそれほど難しいことではありません。文法を正式な言語で記述できるようになると、構文解析が非常に簡単になります (少なくとも、有効な入力の種類を指定できます)。たとえば、問題に対して次の EBNF があるとします。

expression = "every" time-unit|time-unit-list|composite-time-unit
time-unit = { ordinal } "day" | "weekday"
ordinal = "first" | "second" | "third" | ...

等々。これは簡単な仕事ではありません。英文の構文解析では、このようなかなり限定的なものでさえ、かなり関与する可能性があります。しかし、これは確立された厳密な方法です。

文法を定義したら、それ用のパーサーを作成できます。これは、ターミナル(「すべて」など)を探して、それらをルールに一致させることの問題です。たとえば、次のようなものがあるとします (疑似コード)。

words = split(/\s*/,lowercase(input))
if( words[0] == "every" ) {
  switch( words[1] ) {
    case "first":
    case "second":
    case "third":
    ...
      parseTimeUnit(words);
      break;
    case "day":
      everyDay = true;
      break; 
    ...
  }
}

文法の複雑さによっては、Yaccなどを使用してパーサーを自動的に生成することを検討する場合があります。

あなたは問題の塊をかみ砕きましたが、やりがいのある問題です。頑張ってください!

更新: 私が知っている最も古いパーサー ジェネレーターの 1 つであるため、Yacc のみを提案しました。ただし、それらは 100 万個あり、その多くは Javascript を発行します。詳細については、ウィキペディアのパーサー ジェネレーターの比較を参照してください。

于 2012-08-28T01:03:22.920 に答える
0

あなたがやろうとしていることは、文字列をいくつかのデータ構造に解析することであり、正規表現の仕事ではないと私は信じているようです(それはソリューションの一部である可能性がありますが)。

于 2012-08-28T00:54:14.020 に答える