Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Parsing/explode Bible search string into variables or tokens

I need help breaking a Bible search string with PHP into variables or tokens. I'd like to get an explicit usage example of the solution offered in this post: PHP preg_match bible scripture format.

EDIT: the chapter and verses (from, to) are optional.

For example: I'd like to be able to split any of the following strings:

'John 14:16–17'; //Book Chapter:FromVerse-ToVerse
'John 14:16'; //Book Chapter:FromVerse
'John 14'; //Book Chapter
'John'; //BOOK

The following:

<?php
$string = 'Exodus 1:3-7'; // Where Exodus is the book, 1 the chapter number, 3 the starting verse and 7 the ending verse. [Book Chapter:StartVerse-EndVerse]
$pattern = '/[ :-]/';
list( $book, $chapter, $from, $to ) = preg_split($pattern, $string );
echo $book;

Allows me to get the nbook name: Exodus. I could also retrieve the chapter number the same way (echo $chapter), etc.

The problem I'm having with this solution is when the book name has more than one word. Example '1 Samuel 3:4-5'. If I echo $book for example, I get offset 3 not defined or a similar error.

It was suggested in the post linked above that this regex pattern is more complete:

/\w+\s?(\d{1,2})?(:\d{1,2})?([-–]\d{1,2})?(,\s\d{1,2}[-–]\d{1,2})?+$/

I guess my question is how to use this pattern or a similar one to split the search string as described above.

A similar issue is discussed here: PHP problems parsing a bible book string, but I'm just having some trouble modifying the pattern. I keep getting errors like : Undefined offset: 3 ...

I'd appreciate your help

like image 635
TPM Avatar asked Mar 19 '23 14:03

TPM


1 Answers

I wouldn't do that with one regex.

After also reading the Bible-citation - Common formats section in Wikipedia, see my bible-parser idea:

$holy_str = 'Jonny 5:1,4-5,17,21;';

// split verses from book chapters
$parts = preg_split('/\s*:\s*/', trim($holy_str, " ;"));

// init book
$book = array('name' => "", 'chapter' => "", 'verses' => array());

// $part[0] = book + chapter, if isset $part[1] is verses
if(isset($parts[0]))
{
  // 1.) get chapter
  if(preg_match('/\d+\s*$/', $parts[0], $out)) {
    $book['chapter'] = rtrim($out[0]);
  }

  // 2.) book name
  $book['name'] = trim(preg_replace('/\d+\s*$/', "", $parts[0]));
}

// 3.) verses
if(isset($parts[1])) {
  $book['verses'] = preg_split('~\s*,\s*~', $parts[1]);
}

print_r($book);

output (test at eval.in):

Array
(
    [name] => Jonny
    [chapter] => 5
    [verses] => Array
        (
            [0] => 1
            [1] => 4-5
            [2] => 17
            [3] => 21
        )

)

No matter here, if John 14:16 or 12 John: 3, 16-17

Also see regex faq.

like image 79
Jonny 5 Avatar answered Apr 24 '23 21:04

Jonny 5