Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP preg_match bible scripture format

I am struggling with building a regular expression for parsing this kind of strings (bible scriptures):

  'John 14:16–17, 25–26'
  'John 14:16–17'
  'John 14:16'
  'John 14'
  'John'

So the basic pattern is:

Book [[Chapter][:Verse]]

where chapter and verse is optional.

like image 514
Dziamid Avatar asked Apr 02 '12 09:04

Dziamid


3 Answers

I think this does what you need:

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

Assumptions:

  • The numbers are always in sets of either 1 or 2 digits
  • The dash will match either of the following - and

Below is the regex with comments:

"
\w         # Match a single character that is a “word character” (letters, digits, and underscores)
   +          # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
\s         # Match a single character that is a “whitespace character” (spaces, tabs, and line breaks)
   ?          # Between zero and one times, as many times as possible, giving back as needed (greedy)
(          # Match the regular expression below and capture its match into backreference number 1
   \d         # Match a single digit 0..9
      {1,2}      # Between one and 2 times, as many times as possible, giving back as needed (greedy)
)?         # Between zero and one times, as many times as possible, giving back as needed (greedy)
(          # Match the regular expression below and capture its match into backreference number 2
   :          # Match the character “:” literally
   \d         # Match a single digit 0..9
      {1,2}      # Between one and 2 times, as many times as possible, giving back as needed (greedy)
)?         # Between zero and one times, as many times as possible, giving back as needed (greedy)
(          # Match the regular expression below and capture its match into backreference number 3
   [-–]       # Match a single character present in the list “-–”
   \d         # Match a single digit 0..9
      {1,2}      # Between one and 2 times, as many times as possible, giving back as needed (greedy)
)?         # Between zero and one times, as many times as possible, giving back as needed (greedy)
(          # Match the regular expression below and capture its match into backreference number 4
   ,          # Match the character “,” literally
   \s         # Match a single character that is a “whitespace character” (spaces, tabs, and line breaks)
   \d         # Match a single digit 0..9
      {1,2}      # Between one and 2 times, as many times as possible, giving back as needed (greedy)
   [-–]       # Match a single character present in the list “-–”
   \d         # Match a single digit 0..9
      {1,2}      # Between one and 2 times, as many times as possible, giving back as needed (greedy)
)?         # Between zero and one times, as many times as possible, giving back as needed (greedy)
"

And here are some examples of its usage in php:

if (preg_match('/\w+\s?(\d{1,2})?(:\d{1,2})?([-–]\d{1,2})?(,\s\d{1,2}[-–]\d{1,2})?/', $subject)) {
    # Successful match
} else {
    # Match attempt failed
}

Get an array of all matches in a given string

preg_match_all('/\w+\s?(\d{1,2})?(:\d{1,2})?([-–]\d{1,2})?(,\s\d{1,2}[-–]\d{1,2})?/', $subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];
like image 96
Robbie Avatar answered Oct 03 '22 18:10

Robbie


Try this here

\b[a-zA-Z]+(?:\s+\d+)?(?::\d+(?:–\d+)?(?:,\s*\d+(?:–\d+)?)*)?

See and test it here on Regexr

Because of the (?:,\s*\d+(?:–\d+)?)* at the end you can have a list of verses, verses ranges at the end.

like image 25
stema Avatar answered Oct 03 '22 19:10

stema


Use this regex :

[A-Za-z]+( ([0-9]+)(:[0-9]+)?([\-–][0-9]+)?(, [0-9]+[\-–][0-9]+)?)?

Or in its 'prettier' version :

\w+( (\d+)(:\d+)?([\-–]\d+)?(, \d+[\-–]\d+)?)?

UPDATED : To match dashes or hyphens


NOTE : I've tested it and it matches ALL 5 possible versions.

Example : http://regexr.com?30h4q

enter image description here

like image 42
Dr.Kameleon Avatar answered Oct 03 '22 19:10

Dr.Kameleon