Соответствие писанию регулярного выражения

У меня есть следующий код регулярного выражения, который я пытаюсь усовершенствовать для поиска Священных Писаний. ... остальные 66 книг Библии.

/(?=\S)\b(genesis|exodus|leviticus|...)(\.)?(\s)?((\d{1,3})([:,-;]?(?=\d))?((\d{1,3})?([:,-;]?(?=\d))?){0,50})/iu

Где я сталкиваюсь с проблемой, так это в том, что с несколькими ссылками на отрывки, такими как Бытие 3: 2 1 Паралипоменон 2: 2, если я использую регулярное выражение с пробелом в поиске, функция предполагает, что 1 в Паралипоменонах - это Бытие 1 и не распознает его и отправьте preg_replace_callback. Какие-либо предложения?

Ввод представляет собой string, который представляет собой целый абзац, например

Mat 3:12; Luke 3:17; Revelation 16:14 • gathered, 7 Mat 2:4; Mat 22:34; Mat 27:27; Mar 4:1; Mar 5:21; Joh 11:47; Act 4:26 • into, 1 Revelation 13:10 • resorted, 1 Joh 18:2 • themselves, 1 Act 11:26 • together, 24 Mat 13:2; Mat 22:41; Mat 26:3; Mat 27:17; Mat 27:62; Mar 2:2; Mar 6:30; Mar 7:1; Luke 22:66; Joh 11:52; Act 4:6; Act 4:27; Act 4:31; Act 13:44; Act 14:27; Act 15:6; Act 15:30; Act 20:7; Act 20:8; 1 Corinthians 5:4; Revelation 16:16; Revelation 19:17; Revelation 19:19; Revelation 20:8

то, что я пытаюсь сделать, это сделать так, чтобы оно соответствовало Священному Писанию и отрывку, а затем превратить его в ссылку href, используя функцию pre_replace_callback.


person Andrei Chernyshev    schedule 10.06.2015    source источник
comment
Можете ли вы предоставить образцы входных данных и то, что вы хотите получить на выходе?   -  person chris85    schedule 10.06.2015
comment
^ по крайней мере с одним или двумя отрывками до и после проблемного отрывка.   -  person Jacob S    schedule 10.06.2015
comment
Вот еще один пост об этом, чтобы вы начали: stackoverflow.com/questions/9974012/   -  person danielson317    schedule 10.06.2015
comment
Не могли бы вы отредактировать свой вопрос, добавив свои разъяснения, а не комментарии (которые затем можно было бы удалить)?   -  person PJTraill    schedule 11.06.2015


Ответы (1)


В вашем случае вы можете использовать регулярное выражение, предоставленное @danielson317 в комментарии и расширить его в соответствии с вашими потребностями. Он даже правильно обработает «Бытие 3: 2 1 Паралипоменон 2: 2», дав вам <a href...>Genesis 3:2</a> <a href...>1 Chronicles 2:2</a>.

Вы даже можете сделать это классом:

<?php
$scriptureUtils = new ScriptureUtils();
echo $scriptureUtils->addLinks($text);

class ScriptureUtils {

    private $booksAbbreviated = array(
        "Gen", "Exo", "Lev", "Num", "Deu", "Jos", "Jud", "Rut", "1 Sam", "2 Sam", "1 Kin", 
        "2 Kin", "1 Chr", "2 Chr", "Ezr", "Neh", "Est", "Job", "Psa", "Pro", "Ecc", "Son", 
        "Isa", "Jer", "Lam", "Eze", "Dan", "Hos", "Joe", "Amo", "Oba", "Jon", "Mic", 
        "Nah", "Hab", "Zep", "Hag", "Zec", "Mal", "Mat", "Mar", "Luk", "Joh", "Act", 
        "Rom", "1 Cor", "2 Cor", "Gal", "Eph", "Phi", "Col", "1 The", "2 The", "1 Tim", 
        "2 Tim", "Tit", "Phi", "Heb", "Jam", "1 Pet", "2 Pet", "1 Joh", "2 Joh", "3 Joh", 
        "Jud", "Rev"
    );

    private $booksFullnames = array(
        "Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy", "Joshua", "Judges", 
        "Ruth", "1 Samuel", "2 Samuel", "1 Kings", "2 Kings", "1 Chronicles", 
        "2 Chronicles", "Ezra", "Nehemiah", "Esther", "Job", "Psalms", "Proverbs", 
        "Ecclesiastes", "Song of Solomon", "Isaiah", "Jeremiah", "Lamentations", "Ezekiel", 
        "Daniel", "Hosea", "Joel", "Amos", "Obadiah", "Jonah", "Micah", "Nahum", 
        "Habakkuk", "Zephaniah", "Haggai", "Zechariah", "Malachi", "Matthew", "Mark", 
        "Luke", "John", "Acts", "Romans", "1 Corinthians", "2 Corinthians", "Galatians", 
        "Ephesians", "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians", 
        "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James", "1 Peter", 
        "2 Peter", "1 John", "2 John", "3 John", "Jude", "Revelation"
    );

    private $addLinkPattern;

    public function __construct() {
        $this->defineLinkPattern();
    }

    public function addLinks($text) {
        $returnString = preg_replace_callback(
            $this->addLinkPattern,
            array($this, "addLinkCallback"),
            $text
        );
        return $returnString;
    }

    private function addLinkCallback($matches) {
        $returnString = "";
        foreach($matches as $match) {
            $returnString .= "<a href=\"bible.php?passage=$match\">$match</a>";
        }
        return $returnString;
    }

    private function defineLinkPattern() {
        // It is important that the full names appear before the abbreviated ones.
        $bookList = implode("|", array_merge($this->booksFullnames, $this->booksAbbreviated));
        $this->addLinkPattern = "/\\b(?:$bookList)(?:\\s+\\d+)?(?::\\d+(?:–\\d+)?(?:,\\s*\\d+(?:–\\d+)?)*)?/";
    }

}
person Marcos Dimitrio    schedule 13.06.2015