2013-06-02 3 views
1

Я пытаюсь разделить (с preg_split) текст с большим количеством иностранных символов и цифр на слова и цифры с длиной> = 2 и без знака. Теперь у меня есть этот код, но он только разбивается на слова без учета цифр и длины> = 2 для всех. Как я могу сделать?Разделить текст на слова и цифры с поддержкой unicode (preg_split)

$text = 'abc 文 字化け, efg Yukarda mavi gök, asağıda yağız yer yaratıldıkta; (1998 m. siejės 7 d.). Ton pate dėina bandomkojė бойынша бірінші орында тұр (79.65 %), айына 41'; 
$splitted = preg_split('#\P{L}+#u', $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 

Ожидаемый результат должен быть: array('abc', '字化け', 'efg', 'Yukarda', 'mavi', 'gök', 'asağıda', 'yağız', 'yer', 'yaratıldıkta', '1998', 'siejės', 'Ton', 'pate', 'dėina', 'bandomkojė', 'бойынша', 'бірінші', 'орында', 'тұр', '79.65', 'айына', '41');

NB: уже пробовали эти документы link1 & link2, но я не могу получить его работы: -/

+0

Каков фактический результат, который вы получаете? –

+0

На данный момент в результате это: Массив ( [0] => ABC [1] => 文 [2] => 字 化 け [3] => EFG [4] => Yukarda [5] = > Mavi [6] => Gök [7] => asağıda [8] => yagız [9] => Ер [10] => yaratıldıkta [11] => т [12] => siejės [13] => д [14] => Тон [15] => паштет [16] => dėina [17] => bandomkojė [18] => бойынша [19] => бірінші [20] => орында [21] => тұр [22] => айына ) – Albertine

+0

ли вы имеете в виду, что вы _don't_ хотите, чтобы соответствовать на любое слово, которое содержит знаки препинания (т.е. '79 .65 'не соответствует) или вы хотите, чтобы он соответствовал «79» и «65»? – Danack

ответ

1

Использование preg_match_all вместо этого, то вы может проверить состояние длины (что трудно сделать с preg_split, но не невозможно):

$text = 'abc 文 字化け, efg Yukarda mavi gök, asağıda yağız yer yaratıldıkta; (1998 m. siejės 7 d.). Ton pate dėina bandomkojė бойынша бірінші орында тұр (79.65 %), айына 41'; 
preg_match_all('~\p{L}{2,}+|\d{2,}+(?>\.\d++)?|\d\.\d++~u',$text,$matches); 
print_r($matches); 

объяснение:

p{L}{2,}+   # letter 2 or more times 
|     # OR 
    \d{2,}+   # digit 2 or more times 
    (?>\.\d++)?  # can be a decimal number 
|     # OR 
    \d\.\d++   # single digit MUST be followed by at least a decimal 
         # (length constraint) 
+0

Hum, кажется, preg_split более эффективен, чем preg_match_all, вот почему я хотел использовать его (реальный $ text действительно огромный ...). И если мы забудем состояние длины, это возможно? Как я мог объединить [\ P {N}] + и [\ P {L}] + ?? Да, я полностью noob с регулярным выражением: -/ – Albertine

+0

@Albertine: Вы можете составить класс символов, подобный этому '[^ \ p {N} \ p {L}]', но проблема десятичного числа остается. –

+0

@Albertine: IMO, лучший ответ от dev-nul-dweiller, вы можете улучшить его следующим образом: '# \ d ++ \. \ D ++ | [^ \ W _] {2,} + # u' –

1

С небольшой хак, чтобы соответствовать цифр, разделенных точкой перед сопоставлением только цифры как часть слова:

preg_match_all("#(?:\d+\.\d+|\w{2,})#u", $text, $matches); 
$splitted = $matches[0]; 

http://codepad.viper-7.com/X7Ln1V

+0

Спасибо, это регулярное выражение кажется мне совершенно непонятным .. – Albertine

0

Разделительный CJK в «слова» является что-то бессмысленное. Каждый символ - это слово. Если вы используете пробелы, вы разделитесь на фразы.

Так что это зависит от того, что вы на самом деле пытаетесь достичь. Если вы индексируете текст, вам нужно рассмотреть биграмы и/или CJK-идиомы.

+0

Да, это для индексации текста, поэтому я взгляну на эти понятия. Спасибо ! – Albertine

Смежные вопросы