@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at recaptime-dev/main 78 lines 2.0 kB view raw
1<?php 2 3abstract class PhabricatorCustomFieldMonogramParser 4 extends Phobject { 5 6 abstract protected function getPrefixes(); 7 abstract protected function getSuffixes(); 8 abstract protected function getInfixes(); 9 abstract protected function getMonogramPattern(); 10 11 public function parseCorpus($corpus) { 12 $prefixes = $this->getPrefixes(); 13 $suffixes = $this->getSuffixes(); 14 $infixes = $this->getInfixes(); 15 16 $prefix_regex = $this->buildRegex($prefixes); 17 $infix_regex = $this->buildRegex($infixes, true); 18 $suffix_regex = $this->buildRegex($suffixes, true, true); 19 20 $monogram_pattern = $this->getMonogramPattern(); 21 22 $pattern = 23 '/'. 24 '(?:^|\b)'. 25 $prefix_regex. 26 $infix_regex. 27 '((?:'.$monogram_pattern.'(?:\b|$)[,\s]*)+)'. 28 '(?:\band\s+('.$monogram_pattern.'(?:\b|$)))?'. 29 $suffix_regex. 30 '(?:$|\b)'. 31 '/'; 32 33 $matches = null; 34 $ok = preg_match_all( 35 $pattern, 36 $corpus, 37 $matches, 38 PREG_SET_ORDER | PREG_OFFSET_CAPTURE); 39 40 if ($ok === false) { 41 throw new Exception(pht('Regular expression "%s" is invalid!', $pattern)); 42 } 43 44 $results = array(); 45 foreach ($matches as $set) { 46 $monograms = array_filter(preg_split('/[,\s]+/', $set[3][0])); 47 48 if (isset($set[4]) && $set[4][0]) { 49 $monograms[] = $set[4][0]; 50 } 51 52 $results[] = array( 53 'match' => $set[0][0], 54 'prefix' => $set[1][0], 55 'infix' => $set[2][0], 56 'monograms' => $monograms, 57 'suffix' => idx(idx($set, 5, array()), 0, ''), 58 'offset' => $set[0][1], 59 ); 60 } 61 62 return $results; 63 } 64 65 private function buildRegex(array $list, $optional = false, $final = false) { 66 $parts = array(); 67 foreach ($list as $string) { 68 $parts[] = preg_quote($string, '/'); 69 } 70 $parts = implode('|', $parts); 71 72 $maybe_tail = $final ? '' : '\s+'; 73 $maybe_optional = $optional ? '?' : ''; 74 75 return '(?i:('.$parts.')'.$maybe_tail.')'.$maybe_optional; 76 } 77 78}