Home > database >  How to preg_match specific bibles verses and retrieve the book, the chapter and verse in each case
How to preg_match specific bibles verses and retrieve the book, the chapter and verse in each case

Time:06-03

I have read many posts on SO about preg_matching Bible verses but none of them seems to meet my requirement. I am trying to match the following verses with dot all in one preg_match and retrieve the book name the chapter and the verse.

Hebrews 11.6

2 Chronicles 10.16

Romans 13.13

2 Kings 5.10

3 John 1.5

The verses above should respectfully output

I did

if (preg_match('/[ ]{0,}([0-9]{1}[ ]{0,}[a-zA-ZàâäæáãåāèéêëęėēîïīįíìôōøõóòöœùûüūúÿçćčńñÀÂÄÆÁÃÅĀÈÉÊËĘĖĒÎÏĪĮÍÌÔŌØÕÓÒÖŒÙÛÜŪÚŸÇĆČŃÑ]*)[ ]{0,}([0-9]{1,3})[ ]{0,}:[ ]{0,}([0-9]{1,3})[ ]{0,}/', $bible_passage, $ourmatches)) 
    {
        $book = $ourmatches[1];
        
        $chapter = $ourmatches[2];
        
        $verse = $ourmatches[3];
        echo "Book $book chapter  $chapter verse $verse ";

    }

This is able to match those verses but not able to retrieve each book separately with the verse. I want to get the following result

Book Hebrews Chapter 11 verse 6

Book 2 Chronicles Chapter 10 verse 16

Book Romans Chapter 13 verse 13

Book 2 Kings Chapter 5 verse 10

Book 3 John Chapter 1 verse 5

For Hebrews 11.6 what I get is Book 1 Chapter 1 verse 6 instead of Book Hebrews Chapter 1 verse 6

Please how to fix this?

CodePudding user response:

This probably is what you are looking for:

<?php
$data = [
    "Hebrews 11.6",
    "2 Chronicles 10.16",
    "Romans 13.13",
    "2 Kings 5.10",
    "3 John 1.5",
];
array_walk($data, function($entry) {
    preg_match('/(?:(\d )\s )?(\w )\s (\d )\.(\d )/', $entry, $capture);
    list($volume, $book, $chapter, $verse) = array_slice($capture, 1);
    echo "Book $book " . ($volume ? "Volume $volume " : "") . "chapter $chapter verse $verse\n";
});

The output is:

Book Hebrews chapter 11 verse 6

Book Chronicles Volume 2 chapter 10 verse 16

Book Romans chapter 13 verse 13

Book Kings Volume 2 chapter 5 verse 10

Book John Volume 3 chapter 1 verse 5

CodePudding user response:

You can use

<?php

$text = 'Hebrews 11.6
2 Chronicles 10.16
Romans 13.13
2 Kings 5.10
3 John 1.5';
if (preg_match_all('~^(.*?)\h*(\d )\.(\d )$~m', $text, $ms, PREG_SET_ORDER, 0)) {
    foreach ($ms as $m) {
        $book=$m[1];
        $chapter=$m[2];
        $verse=$m[3];
        echo "Book $book chapter $chapter verse $verse\n";
    }
}

See the PHP demo, and the regex demo.

Output:

Book Hebrews chapter 11 verse 6
Book 2 Chronicles chapter 10 verse 16
Book Romans chapter 13 verse 13
Book 2 Kings chapter 5 verse 10
Book 3 John chapter 1 verse 5

Regex details:

  • ^ - start of a line (due to m flag)
  • (.*?) - any text, as short as possible
  • \h* - zero or more horizontal whites[ace
  • (\d ) - Group 2: one or more digits
  • \. - a dot
  • (\d ) - Group 3: one or more digits
  • $ - end of string.
  • Related