Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Regex Expression Involving Japanese

My goal is to filter through a Microsoft Word Document (.docx) grabbing all Japanese kanji and kana. The current code I am working with is the following:

preg_match_all('~[\x{4e00}-\x{9faf}]([\x{3040}-\x{309f}]) \= ([a-z]) \=+~u', $data, $matches);

According to some research I discovered the unicode values of Japanese text as follows: http://www.rikai.com/library/kanjitables/kanji_codes.unicode.shtml

An example of the data I am working with looks like this:

時(とき) = toki = time; hour; occasion; momentを = wo = particle marking the direct object of the sentence(時 = time)超えて(こえて) = koete = cross

My end goal is to be able to run a preg_match_all fetching data in a similar pattern that looks like "超えて(こえて) = koete" The information before the ( and the information inside ( ) and the romanization after between = =

The result I am looking for would be a returned array that looks like:

array(
    0 => array('時', 'とき', 'toki'),
    1 => array('超えて', 'こえて', 'koete')
);

The first result in each array includes both "Kanji, Hiragana, and possibly Katakana" while the 2nd result is only Hiragana and the third result is only regular alphabetic characters. I'm not too great with regex and add Japaense unicode and I'm clueless, any help would really be appreciated! Thanks!

like image 979
Bryse Meijer Avatar asked Apr 26 '11 23:04

Bryse Meijer


1 Answers

You can use the special Unicode regex placeholders instead of the numeric ranges if you use the /u modifier:

preg_match_all('/
    ([\p{Han}\p{Katakana}\p{Hiragana}]+)    # Kanji
    (?: [(]                                 # optional part: paren (
    ([\p{Hiragana}]+)                       # Hiragana
    [)] )?                                  # closing paren )
    \s*=\s*                                 # spaces and =
    ([\w\s;=]+)                             # English letters
    /ux',
    $source,  $matches, PREG_SET_ORDER
);
print_r($matches);

I've notices the Hiragana in parens is optional, so I made your regex a bit more complex with (?: ... )? which optionalizes that part.

Note that the result ordering is a bit different, because preg_match_all keeps the complete match string in index [0] usually:

[0] => Array
    (
        [0] => 時(とき) = toki = time; hour; occasion; moment
        [1] => 時
        [2] => とき
        [3] => toki = time; hour; occasion; moment
    )
like image 84
mario Avatar answered Oct 11 '22 07:10

mario