I18N_Arabic
[ class tree: I18N_Arabic ] [ index: I18N_Arabic ] [ all elements ]

Source for file WordTag.php

Documentation is available at WordTag.php

  1. <?php
  2. /**
  3.  * ----------------------------------------------------------------------
  4.  *  
  5.  * Copyright (c) 2006-2016 Khaled Al-Sham'aa.
  6.  *  
  7.  * http://www.ar-php.org
  8.  *  
  9.  * PHP Version 5
  10.  *  
  11.  * ----------------------------------------------------------------------
  12.  *  
  13.  * LICENSE
  14.  *
  15.  * This program is open source product; you can redistribute it and/or
  16.  * modify it under the terms of the GNU Lesser General Public License (LGPL)
  17.  * as published by the Free Software Foundation; either version 3
  18.  * of the License, or (at your option) any later version.
  19.  *  
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU Lesser General Public License for more details.
  24.  *  
  25.  * You should have received a copy of the GNU Lesser General Public License
  26.  * along with this program.  If not, see <http://www.gnu.org/licenses/lgpl.txt>.
  27.  *  
  28.  * ----------------------------------------------------------------------
  29.  *  
  30.  * Class Name: Tagging Arabic Word Class
  31.  *  
  32.  * Filename: WordTag.php
  33.  *  
  34.  * Original  Author(s): Khaled Al-Sham'aa <khaled@ar-php.org>
  35.  *  
  36.  * Purpose:  Arabic grammarians describe Arabic as being derived from
  37.  *           three main categories: noun, verb and particle. This class
  38.  *           built to recognize the class of a given Arabic word.
  39.  *            
  40.  * ----------------------------------------------------------------------
  41.  *  
  42.  * Tagging Arabic Word
  43.  *
  44.  * This PHP Class can identifying names, places, dates, and other noun
  45.  * words and phrases in Arabic language that establish the meaning of a body
  46.  * of text.
  47.  * 
  48.  * This process of identifying names, places, dates, and other noun words and
  49.  * phrases that establish the meaning of a body of text-is critical to software
  50.  * systems that process large amounts of unstructured data coming from sources such
  51.  * as email, document files, and the Web.
  52.  * 
  53.  * Arabic words are classifies into three main classes, namely, verb, noun and
  54.  * particle. Verbs are sub classified into three subclasses (Past verbs, Present
  55.  * Verbs, etc.); nouns into forty six subclasses (e.g. Active participle, Passive
  56.  * participle, Exaggeration pattern, Adjectival noun, Adverbial noun, Infinitive
  57.  * noun, Common noun, Pronoun, Quantifier, etc.) and particles into twenty three
  58.  * subclasses (e.g. additional, resumption, Indefinite, Conditional, Conformational,
  59.  * Prohibition, Imperative, Optative, Reasonal, Dubious, etc.), and from these three
  60.  * main classes that the rest of the language is derived.
  61.  * 
  62.  * The most important aspect of this system of describing Arabic is that all the
  63.  * subclasses of these three main classes inherit properties from the parent
  64.  * classes.
  65.  * 
  66.  * Arabic is very rich in categorising words, and contains classes for almost every
  67.  * form of word imaginable. For example, there are classes for nouns of instruments,
  68.  * nouns of place and time, nouns of activity and so on. If we tried to use all the
  69.  * subclasses described by Arabic grammarians, the size of the tagset would soon
  70.  * reach more than two or three hundred tags. For this reason, we have chosen only
  71.  * the main classes. But because of the way all the classes inherit from others, it
  72.  * would be quite simple to extend this tagset to include more subclasses.
  73.  *
  74.  * Example:
  75.  * <code>
  76.  *     include('./I18N/Arabic.php');
  77.  *     $obj = new I18N_Arabic('WordTag');
  78.  * 
  79.  *     $hStr=$obj->highlightText($str,'#80B020');
  80.  * 
  81.  *     echo $str . '<hr />' . $hStr . '<hr />';
  82.  *     
  83.  *     $taggedText = $obj->tagText($str);
  84.  * 
  85.  *     foreach($taggedText as $wordTag) {
  86.  *         list($word, $tag) = $wordTag;
  87.  *     
  88.  *         if ($tag == 1) {
  89.  *             echo "<font color=#DBEC21>$word is Noun</font>, ";
  90.  *         }
  91.  *     
  92.  *         if ($tag == 0) {
  93.  *             echo "$word is not Noun, ";
  94.  *         }
  95.  *     }
  96.  * </code>
  97.  *    
  98.  * @category  I18N
  99.  * @package   I18N_Arabic
  100.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  101.  * @copyright 2006-2016 Khaled Al-Sham'aa
  102.  *    
  103.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  104.  * @link      http://www.ar-php.org
  105.  */
  106.  
  107. /**
  108.  * This PHP class to tagging Arabic Word
  109.  *  
  110.  * @category  I18N
  111.  * @package   I18N_Arabic
  112.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  113.  * @copyright 2006-2016 Khaled Al-Sham'aa
  114.  *    
  115.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  116.  * @link      http://www.ar-php.org
  117.  */ 
  118. {
  119.     private static $_particlePreNouns array('عن''في''مذ''منذ',
  120.                                               'من''الى''على''حتى',
  121.                                               'الا''غير''سوى''خلا',
  122.                                               'عدا''حاشا''ليس');
  123.  
  124.     private static $_normalizeAlef       array('أ','إ','آ');
  125.     private static $_normalizeDiacritics array('َ','ً','ُ','ٌ',
  126.                                                  'ِ','ٍ','ْ','ّ');
  127.  
  128.     private $_commonWords array();
  129.  
  130.     /**
  131.      * Loads initialize values
  132.      *
  133.      * @ignore
  134.      */         
  135.     public function __construct()
  136.     {
  137.         $words file(dirname(__FILE__).'/data/ar-stopwords.txt');
  138.         $words array_map('trim'$words);
  139.         
  140.         $this->_commonWords $words;
  141.     }
  142.     
  143.     /**
  144.      * Check if given rabic word is noun or not
  145.      *      
  146.      * @param string $word       Word you want to check if it is
  147.      *                            noun (utf-8)
  148.      * @param string $word_befor The word before word you want to check
  149.      *                    
  150.      * @return boolean TRUE if given word is Arabic noun
  151.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  152.      */
  153.     public static function isNoun($word$word_befor)
  154.     {
  155.         $word       trim($word);
  156.         $word_befor trim($word_befor);
  157.  
  158.         $word       str_replace(self::$_normalizeAlef'ا'$word);
  159.         $word_befor str_replace(self::$_normalizeAlef'ا'$word_befor);
  160.         $wordLen    strlen($word);
  161.         
  162.         // إذا سبق بحرف جر فهو اسم مجرور
  163.         if (in_array($word_beforself::$_particlePreNouns)) {
  164.             return true;
  165.         }
  166.         
  167.         // إذا سبق بعدد فهو معدود
  168.         if (is_numeric($word|| is_numeric($word_befor)) {
  169.             return true;
  170.         }
  171.         
  172.         // إذا كان منون
  173.         if (mb_substr($word-11== 'ً' || mb_substr($word-11== 'ٌ' 
  174.             || mb_substr($word-11== 'ٍ'
  175.         {
  176.             return true;
  177.         }
  178.         
  179.         $word    str_replace(self::$_normalizeDiacritics''$word);
  180.         $wordLen mb_strlen($word);
  181.         
  182.         // إن كان معرف بأل التعريف
  183.         if (mb_substr($word01== 'ا' && mb_substr($word11== 'ل' 
  184.             && $wordLen >= 5
  185.         {
  186.             return true;
  187.         }
  188.         
  189.         // إذا كان في الكلمة  ثلاث ألفات
  190.         // إن لم تكن الألف الثالثة متطرفة
  191.         if (mb_substr_count($word'ا'>= 3{
  192.             return true;
  193.         }
  194.  
  195.         //إن كان مؤنث تأنيث لفظي، منتهي بتاء مربوطة
  196.         // أو همزة أو ألف مقصورة
  197.         if ((mb_substr($word-11== 'ة' || mb_substr($word-11== 'ء' 
  198.             || mb_substr($word-11== 'ى'&& $wordLen >= 4
  199.         {
  200.             return true;
  201.         }
  202.  
  203.         // مؤنث تأنيث لفظي،
  204.         // منتهي بألف وتاء مفتوحة - جمع مؤنث سالم
  205.         if (mb_substr($word-11== 'ت' && mb_substr($word-21== 'ا' 
  206.             && $wordLen >= 5
  207.         {
  208.             return true;
  209.         }
  210.  
  211.         // started by Noon, before REH or LAM, or Noon, is a verb and not a noun
  212.         if (mb_substr($word01== 'ن' && (mb_substr($word11== 'ر' 
  213.             || mb_substr($word11== 'ل' || mb_substr($word11== 'ن'
  214.             && $wordLen 3
  215.         {
  216.             return false;
  217.         }
  218.         
  219.         // started by YEH, before some letters is a verb and not a noun
  220.         // YEH,THAL,JEEM,HAH,KHAH,ZAIN,SHEEN,SAD,DAD,TAH,ZAH,GHAIN,KAF
  221.         $haystack 'يذجهخزشصضطظغك';
  222.         if (mb_substr($word01== 'ي' 
  223.             && (mb_strpos($haystackmb_substr($word11)) !== false
  224.             && $wordLen 3
  225.         {
  226.             return false;
  227.         }
  228.         
  229.         // started by beh or meem, before BEH,FEH,MEEM is a noun and not a verb
  230.         if ((mb_substr($word01== 'ب' || mb_substr($word01== 'م'
  231.             && (mb_substr($word11== 'ب' || mb_substr($word11== 'ف' 
  232.             || mb_substr($word11== 'م'&& $wordLen 3
  233.         {
  234.             return true;
  235.         }
  236.         
  237.         // الكلمات التي  تنتهي بياء ونون
  238.         // أو ألف ونون أو ياء ونون
  239.         // تكون أسماء ما لم تبدأ بأحد حروف المضارعة 
  240.         if (preg_match('/^[^ايتن]\S{2}[اوي]ن$/u'$word)) {
  241.             return true;
  242.         }
  243.  
  244.         // إن كان على وزن اسم الآلة
  245.         // أو اسم المكان أو اسم الزمان
  246.         if (preg_match('/^م\S{3}$/u'$word
  247.             || preg_match('/^م\S{2}ا\S$/u'$word)  
  248.             || preg_match('/^م\S{3}ة$/u'$word)  
  249.             || preg_match('/^\S{2}ا\S$/u'$word)  
  250.             || preg_match('/^\Sا\Sو\S$/u'$word)  
  251.             || preg_match('/^\S{2}و\S$/u'$word)  
  252.             || preg_match('/^\S{2}ي\S$/u'$word)  
  253.             || preg_match('/^م\S{2}و\S$/u'$word)  
  254.             || preg_match('/^م\S{2}ي\S$/u'$word)  
  255.             || preg_match('/^\S{3}ة$/u'$word
  256.             || preg_match('/^\S{2}ا\Sة$/u'$word)  
  257.             || preg_match('/^\Sا\S{2}ة$/u'$word)  
  258.             || preg_match('/^\Sا\Sو\Sة$/u'$word)  
  259.             || preg_match('/^ا\S{2}و\Sة$/u'$word)  
  260.             || preg_match('/^ا\S{2}ي\S$/u'$word
  261.             || preg_match('/^ا\S{3}$/u'$word)  
  262.             || preg_match('/^\S{3}ى$/u'$word)  
  263.             || preg_match('/^\S{3}اء$/u'$word)  
  264.             || preg_match('/^\S{3}ان$/u'$word)  
  265.             || preg_match('/^م\Sا\S{2}$/u'$word)  
  266.             || preg_match('/^من\S{3}$/u'$word)  
  267.             || preg_match('/^مت\S{3}$/u'$word)  
  268.             || preg_match('/^مست\S{3}$/u'$word)  
  269.             || preg_match('/^م\Sت\S{2}$/u'$word)  
  270.             || preg_match('/^مت\Sا\S{2}$/u'$word
  271.             || preg_match('/^\Sا\S{2}$/u'$word)
  272.         {
  273.             return true;
  274.         }
  275.  
  276.         return false;
  277.     }
  278.     
  279.     /**
  280.      * Tag all words in a given Arabic string if they are nouns or not
  281.      *      
  282.      * @param string $str Arabic string you want to tag all its words
  283.      *                    
  284.      * @return array Two dimension array where item[i][0] represent the word i
  285.      *                in the given string, and item[i][1] is 1 if that word is
  286.      *                noun and 0 if it is not
  287.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  288.      */
  289.     public static function tagText($str)
  290.     {
  291.         $text     array();
  292.         $words    explode(' '$str);
  293.         $prevWord '';
  294.         
  295.         foreach ($words as $word{
  296.             if ($word == ''{
  297.                 continue;
  298.             }
  299.  
  300.             if (self::isNoun($word$prevWord)) {
  301.                 $text[array($word1);
  302.             else {
  303.                 $text[array($word0);
  304.             }
  305.             
  306.             $prevWord $word;
  307.         }
  308.  
  309.         return $text;
  310.     }
  311.     
  312.     /**
  313.      * Highlighted all nouns in a given Arabic string
  314.      *      
  315.      * @param string $str   Arabic string you want to highlighted
  316.      *                       all its nouns
  317.      * @param string $style Name of the CSS class you would like to apply
  318.      *                    
  319.      * @return string Arabic string in HTML format where all nouns highlighted
  320.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  321.      */
  322.     public static function highlightText($str$style null)
  323.     {
  324.         $html     '';
  325.         $prevTag  0;
  326.         $prevWord '';
  327.         
  328.         $taggedText self::tagText($str);
  329.         
  330.         foreach ($taggedText as $wordTag{
  331.             list($word$tag$wordTag;
  332.             
  333.             if ($prevTag == 1{
  334.                 if (in_array($wordself::$_particlePreNouns)) {
  335.                     $prevWord $word;
  336.                     continue;
  337.                 }
  338.                 
  339.                 if ($tag == 0{
  340.                     $html .= "</span> \r\n";
  341.                 }
  342.             else {
  343.                 // if ($tag == 1 && !in_array($word, $this->_commonWords)) {
  344.                 if ($tag == 1{
  345.                     $html .= " \r\n<span class=\"" $style ."\">";
  346.                 }
  347.             }
  348.             
  349.             $html .= ' ' $prevWord ' ' $word;
  350.             
  351.             if ($prevWord != ''{
  352.                 $prevWord '';
  353.             }
  354.             $prevTag $tag;
  355.         }
  356.         
  357.         if ($prevTag == 1{
  358.             $html .= "</span> \r\n";
  359.         }
  360.         
  361.         return $html;
  362.     }
  363. }

Documentation generated on Fri, 01 Jan 2016 10:26:31 +0200 by phpDocumentor 1.4.0