Search code examples
phparraysregextextexplode

How to add a description of words from text to an array, to an array key by passing words?


I have a book in which there are many words in this form:

ОБАНДОМ آباندام маљ. обпайкар, нозукан- дом, латифбадан.
FБАФКАН آبافكن муњаррики обафкан, даст- гоњи обпошї.
БАНЉИР انجير آب обе, ки дар он анљири ќоќ
ва хушкро мељӯшонанд ва он хусусияти
табобатї дорад.
ӮББАДАЛ بدل آب муовизаи об, табдили об.
ТББАНД بند آب 1. он ки дар пеши об банд ё
дарѓот месозад. 2. банд, дарѓот.
ОББАР بر آب 1. он ки об мебарад, обкаш, маш- коб. 2. маљ. маъшуќ, ки тавассути њуснаш
обрўи ошиќи худро зери хавфи коҳиш
мегузорад. 3. тех. облўла, лўлаи обрасонї, ќубури обгузар.
ЗББАРДОР آببردار 1. обро ба худ гиранда, он
чи зиёд об талаб мекунад, обталаб; биринљи
оббардор. 2. ниг. обчинак.
ҚББАРДОРЇ آببرداري 1. обкашї, машкобї. 2.
об бардоштани чизе (мас., биринљ).
ҶББАРДОШТА برداشته آب рахнае, ки бо фишор
ё љараёни об ба амал омадааст, оббурда, об- шуста (мас., дар банди об ё замин).
ӢББАРО برا آب љои баромади об, љое, ки об аз
он љорї мешавад.
ЪББАЊО بها آب кит. музди об, пули об.
ӢББО اآب нидо, лањљ. изњори тааљљуб ва афсўс.
РББОЗ باز آب шиновар, ѓаввос, обдон, оббур.
ОББОЗИДОРЇ بازيداري آبоббозї доштан
(мас., кўдакро, беморро ва ѓ.)
ОББОЗЇ آببازي шиноварї, оббурї; оббозї кар- дан ба об даромадан ва шустушў кардан, шино кардан.
СББУР بر آب 1. ниг. оббоз. 2. бахши пеши поя- њои пулу купрукњо муќобили љараёни об, ки
нўгтез буда, мављњои обро таќсим карда, фишори обро бар сутуни пояњо суст мекунад.
ОББУРДА برده آب 1. љои рахна карда хокро
шуста бурдаи об, љои обшустаи дарѓот. 2.
љар, љарї, сой.
ҲББУРЇ بري آب обро бурида гузаштан, шиноварї.
ОБВАРЗ ورز آب обдон, оббоз, шиновар.
ДБВАРЗЇ ورزي آب оббозї, шиноварї.
УБГАЗ آبگز осебдида ва зарардида бар асари
муддати зиёд зери об мондан.
ОБГАРДИШ گردش آب 1. хамгашт (-и дарё). 2.
гирдоб. 3. таѓйири мусбат ва ё манфии таб- дили иќлим ба саломатї; нотобї бар асари
табдили иќлим. 4. кит. тезрафтор, хушраф- тор.

As you see all the words that you need to add to the key of the array are written with large letters. By passing these words to the array key, I want to add all the description of these words to the array. How can I do this through regular expression?

The approximate result looks as follows:

$wordsDescription = array(
    "ОБАНДОМ" => "آباندام маљ. обпайкар, нозукан- дом, латифбадан.",
    "FБАФКАН" => "آبافكن муњаррики обафкан, даст- гоњи обпошї.",
    "БАНЉИР" => "نجير آب обе, ки дар он анљири ќоќ ва хушкро мељӯшонанд ва он хусусияти табобатї дорад.",
    "ӮББАДАЛ" => "بدل آب муовизаи об, табдили об.",
    "ТББАНД" => "بند آب 1. он ки дар пеши об банд ё дарѓот месозад. 2. банд, дарѓот.",
    "ОББАР" => "بر آب 1. он ки об мебарад, обкаш, маш- коб. 2. маљ. маъшуќ, ки тавассути њуснаш обрўи ошиќи худро зери хавфи коҳиш мегузорад. 3. тех. облўла, лўлаи брасонї, ќубури обгузар.",
    .................
    "ОБГАРДИШ" => "گردش آب 1. хамгашт (-и дарё). 2. гирдоб. 3. таѓйири мусбат ва ё манфии таб- дили иќлим ба саломатї; нотобї бар асари табдили иќлим. 4. кит. тезрафтор, хушраф- тор."
);

If possible then the second array with the second result

$wordsTranslate = array(
    "ОБАНДОМ" => "آباندام",
    "FБАФКАН" => "آبافكن",
    ....................,
    "ОБГАРДИШ" => "گردش آب"
);

Solution

  • You may capture the words with the descriptions with

    ~^(\p{Lu}+)\h+(.*(?:\R(?!\p{Lu}+\h).*)*)~mu
    

    See the regex demo.

    Details

    • ^ - start of a line (due to the m modifier)
    • (\p{Lu}+) - 1 or more uppercase Unicode letters
    • \h+ - 1 or more horizontal whitespace
    • (.*(?:\R(?!\p{Lu}+\h).*)*) - Group 2:
      • .* - the rest of the line
      • (?:\R(?!\p{Lu}+\h).*)* - 0 or more sequences of
        • \R(?!\p{Lu}+\h) - a line break sequence not followed with 1+ uppercase Unicode letters and 1 horizontal whitespace
        • .* - the rest of the line.

    See the PHP demo:

    $s = "ОБАНДОМ آباندام маљ. обпайкар, нозукан- дом, латифбадан.\nFБАФКАН آبافكن муњаррики обафкан, даст- гоњи обпошї.\nБАНЉИР انجير آب обе, ки дар он анљири ќоќ\nва хушкро мељӯшонанд ва он хусусияти\nтабобатї дорад.\nӮББАДАЛ بدل آب муовизаи об, табдили об.";
    $re = '~^(\p{Lu}+)\h+(.*(?:\R(?!\p{Lu}+\h).*)*)~mu';
    preg_match_all($re, $s, $m);
    $result = array_combine($m[1], $m[2]);
    print_r($result);
    

    Output:

    Array
    (
        [ОБАНДОМ] => آباندام маљ. обпайкар, нозукан- дом, латифбадан.
        [FБАФКАН] => آبافكن муњаррики обафкан, даст- гоњи обпошї.
        [БАНЉИР] => انجير آب обе, ки дар он анљири ќоќ
    ва хушкро мељӯшонанд ва он хусусияти
    табобатї дорад.
        [ӮББАДАЛ] => بدل آب муовизаи об, табдили об.
    )
    

    You may "shrink" the line breaks using

    $result = array_combine($m[1], preg_replace('~\s*\R\s*~u', ' ', $m[2]));
    

    See another PHP demo. The \s*\R\s* pattern matches any 0+ whitespaces followed with an obligatory line break sequence followed with any 0+ whitespaces, and replaces the matches with a regular space.

    The second array can easily be built by removing all the non-Arabic chars from the description values:

    $second = array_combine($m[1], preg_replace('~\P{Arabic}+~u', '', $m[2]));
    print_r($second);
    

    See this PHP demo.