1

聖書検索を作成しています。聖書検索の問題点は、人々がさまざまな種類の検索を入力することが多いため、それに応じて検索を分割する必要があることです。だから私は、最初にすべてのスペースを削除し、そこで文字列を処理するのが最善の方法だと考えました。さまざまなタイプの検索は次のようになります。

Genesis 1:1- 創世記 1 章 1 節

1 Kings 2:5- 列王記第 2 章 5 節

Job 3- ジョブ3章

Romans 8:1-7- ローマ人への手紙 8 章 1 節から 7 節

1 John 5:6-11- 1 ヨハネ 5 章 6 節 - 11 節。

私はさまざまなタイプの検索にあまり慣れていませんが、これを行うためのより簡単な方法を見つけることができるか、これを行うための優れた方法を知っている場合は、その方法を教えてください!

ありがとう

4

5 に答える 5

1

ここで行う最も簡単な方法は、正規表現を記述してテキストをキャプチャし、キャプチャを解析して結果を確認することです。まず、テスト ベンチがあると仮定します。

$tests = array( 
    'Genesis 1:1' => 'Genesis Chapter 1, Verse 1',
    '1 Kings 2:5' => '1 Kings Chapter 2, Verse 5',
    'Job 3' => 'Job Chapter 3',
    'Romans 8:1-7' => 'Romans Chapter 8, Verses 1 to 7',
    '1 John 5:6-11' => '1 John Chapter 5, Verses 6 to 11'
);

つまり、左から右に次のようになります。

  1. ブック名。オプションで番号の前に付けます
  2. 章番号
  3. オプションの節番号。オプションで、その後に範囲が続きます。

したがって、これらすべてのケースに一致する正規表現を作成できます。

((?:\d+\s)?\w+)\s+(\d+)(?::(\d+(?:-\d+)?))?

そして、正規表現から返される結果を見てみましょう:

foreach( $tests as $test => $answer) {
    // Match the regex against the test case
    preg_match( $regex, $test, $match);

    // Ignore the first entry, the 2nd and 3rd entries hold the book and chapter
    list( , $book, $chapter) = array_map( 'trim', $match);

    $output = "$book Chapter $chapter";

    // If the fourth match exists, we have a verse entry
    if( isset( $match[3])) {
        // If there is no dash, it's a single verse
        if( strpos( $match[3], '-') === false) {
            $output .= ", Verse " . $match[3];
        } else {
            // Otherwise it's a range of verses
            list( $start, $end) = explode( '-', $match[3]);
            $output .= ", Verses $start to $end";
        }
    }
    // Here $output matches the value in $answer from our test cases
    echo $answer . "\n" . $output . "\n\n";
}

このデモで動作することがわかります。

于 2012-10-30T15:32:46.060 に答える
0

さて、正規表現についてはよくわかりませんが、まだ調べていないので、より手続き的なアプローチにこだわっています。私は次のことを行いました (これは、私が達成しようとしていた 5 年前に書いたコードを大幅に改善したものです)。

まず、この関数が必要です。

    function varType($str) {
        if(is_numeric($str)) {return false;}    
        if(is_string($str)) {return true;}  
    }


    $bible = array("BookNumber" => "", "Book" => "", "Chapter" => "", "StartVerse" => "", "EndVerse" => "");    
  $pos = 1; // 1 - Book Number
        // 2 - Book 
        // 3 - Chapter 
        // 4 - ':' or 'v'
        // 5 - StartVerse
        // 6 - is a dash for spanning verses '-'
        // 7 - EndVerse
    $scan = ""; $compile = array();
    //Divide into character type groups.    
    for($x=0;$x<=(strlen($collapse)-1);$x++)
    {   if($x>=1) {if(varType($collapse[$x]) != varType($collapse[$x-1])) {array_push($compile,$scan);$scan = "";}}
        $scan .= $collapse[$x];
        if($x==strlen($collapse)-1) {array_push($compile,$scan);}
    }
    //If the first element is not a number, then it is not a numbered book (AKA 1 John, 2 Kings), So move the position forward.
    if(varType($compile[0])) {$pos=2;}
    foreach($compile as $val)
    {   if(!varType($val)) 
        {   switch($pos) 
            {   case 1: $bible['BookNumber'] = $val;    break;      
                case 3: $bible['Chapter'] = $val;   break; 
                case 5: $bible['StartVerse'] = $val;    break; 
                case 7: $bible['EndVerse'] = $val;  break; 
            }
        } else {switch($pos) 
            {   case 2: $bible['Book'] = $val;      break;      
                case 4:     //Colon or 'v'
                case 6: break;  //Dash for verse spanning. 
            }}
        $pos++;
    }

これにより、最後に「Bible」と呼ばれる配列が得られ、SQL データベースで実行するために必要なすべてのデータが含まれます。これが他の人に役立つことを願っています。

于 2012-10-30T14:46:17.553 に答える
0

私はあなたがここで尋ねていることを理解していると思います。情報を抽出するアルゴリズムを考案したい (例: 書籍名、章、節)。

これは、パターン マッチング (例: 正規表現) の仕事のように思えます。パターンを定義し、意味のあるすべてのシナリオのデータを抽出し、そこから作業できるからです。

実際にはかなりの数の亜種が存在する可能性があります。おそらく、自然言語処理についても検討する必要があります。名前のファジー文字列一致により、より良い結果が得られる可能性があります (例: 書籍名のスペルミス)。

幸運を祈ります

于 2012-10-30T14:17:56.057 に答える
0

次のように、preg_match_all に基づいて何かを試してください。

$ php -a
Interactive shell

php > $s = '1 kings 2:4 and 1 sam 4-5';
php > preg_match_all("/(\\d*|[^\\d ]*| *)/", $s, $parts);
php > print serialize($s);
于 2012-10-30T14:22:15.283 に答える
0

私はこれがクレイジーな話であることを知っています.

  1. 始まりの詩
  2. エンディングの詩[オプション]
于 2012-10-30T15:04:12.490 に答える