fork download
  1. <?php
  2. function get_chapter($text, $terms) {
  3.  
  4. if (empty($text)) return;
  5. if (empty($terms) || !is_array($terms)) return;
  6.  
  7. $values = false;
  8.  
  9. $terms_quoted = array();
  10. //make e.g. "chapters" match either "c" OR "Chapters"
  11. foreach ($terms as $term)
  12. //revert this to your previous one if you want the "terms" provided explicitly
  13. $terms_quoted[] = $term[0].'('.preg_quote(substr($term,1), '/').')?';
  14.  
  15. $matcher = '/(('.implode('|', $terms_quoted).')\s*(\d+(?:\s*[&+,.-]*\s*?)*)+)+/i';
  16.  
  17. //match the "chapter" expressions you provided
  18. if (preg_match($matcher, $text, $matches)) {
  19. if (!empty($matches[0])) {
  20.  
  21. //extract the numbers, in order, paying attention to existing hyphen/range identifiers
  22. if (preg_match_all('/\d+(?:\.\d+)?|-+/', $matches[0], $numbers)) {
  23. $bot = NULL;
  24. $top = NULL;
  25. $nextIsTop = false;
  26. $results = array();
  27. $setv = function(&$b,&$t,$v){$b=$v;$t=$v;};
  28. $flatten = function(&$b,&$t,$n,&$r){$x=$b;if($b!=$t)$x=$x.'-'.$t;array_push($r,$x);$b=$n;$t=$n;return$r;};
  29. foreach ($numbers[0] as $num) {
  30. if ($num == '-') $nextIsTop = true;
  31. elseif ($nextIsTop) {
  32. $top = $num;
  33. $nextIsTop = false;
  34. }
  35. elseif (is_null($bot)) $setv($bot,$top,$num);
  36. elseif ($num - $top > 1) $flatten($bot,$top,$num,$results);
  37. else $top = $num;
  38. }
  39. return implode(' & ', $flatten ($bot,$top,$num,$results));
  40. }
  41. }
  42. }
  43. }
  44.  
  45.  
  46. $text = array('9 text chapter 25.6 text', // c25.6
  47. 'text chapter 25.6 text', // c25.6
  48. 'text chapters 23, 24, 25 text', // c23-25
  49. 'chapters 23+24+25 text', // c23-25
  50. 'chapter 23, 25 text', // c23 & 25
  51. 'text chapter 23 & 24 & 25 text', // c23-25
  52. 'text c25.5-30 text', // c25.5-30
  53. 'text c99-c102 text', // c99-102
  54. 'text chapter 99 - chapter 102 text', // c99-102
  55. 'text chapter 1 - 3 text', // c1-3
  56. '33 text chapter 1, 2 text 3', // c1-2
  57. 'text v2c5-10 text', // c5-10
  58. 'text chapters 23, 24, 25, 29, 31, 32 text', // c23-25 & 29 & 31-32
  59. );
  60. $terms = array('chapter', 'chapters');
  61. foreach ($text as $snippet)
  62. {
  63. $chapter = get_chapter($snippet, $terms);
  64. print("Chapter is: c".$chapter."\n");
  65. //print_r($chapter);
  66.  
  67. //if ($chapter) {
  68. // echo 'Chapter is: '. $chapter;
  69. //
  70. //}
  71. }
  72.  
  73.  
  74.  
  75.  
  76.  
Success #stdin #stdout 0.02s 23852KB
stdin
Standard input is empty
stdout
Chapter is: c25.6
Chapter is: c25.6
Chapter is: c23-25
Chapter is: c23-25
Chapter is: c23 & 25
Chapter is: c23-25
Chapter is: c25.5-30
Chapter is: c99-102
Chapter is: c99-102
Chapter is: c1-3
Chapter is: c1-2
Chapter is: c5-10
Chapter is: c23-25 & 29 & 31-32