النص انقسم الى PHP الكلمات المشكلة، مشكلة معقدة

StackOverflow https://stackoverflow.com/questions/1600649

  •  05-07-2019
  •  | 
  •  

سؤال

واني اسعى الى تقسيم النص إلى كلام:

$delimiterList = array(" ", ".", "-", ",", ";", "_", ":",
           "!", "?", "/", "(", ")", "[", "]", "{", "}", "<", ">", "\r", "\n",
           '"');
$words = mb_split($delimiterList, $string);

والذي يعمل بشكل جيد جدا مع سلاسل ولكن أنا عالقة في بعض الحالات التي يجب أن أقوم به مع الأرقام.

ومنها مثلا. إذا كان لدي نص "انظروا إلى النتيجة this.My هو 3.14، وأنا سعيدة حول هذا الموضوع". الآن مجموعة هي

[0]=>Look,
[1]=>at,
[2]=>this,
[3]=>My,
[4]=>score,
[5]=>is,
[6]=>3,
[7]=>14,
[8]=>and, ....

وبعد ذلك أيضا يتم تقسيم 3.14 في 3 و 14 والتي لا ينبغي أن يحدث في حالتي. أعني النقطة يجب تقسيم سلسلتين ولكن ليس رقمين. وينبغي أن يكون مثل:

[0]=>Look,
[1]=>at,
[2]=>this,
[3]=>My,
[4]=>score,
[5]=>is,
[6]=>3.14,
[7]=>and, ....

ولكن ليس لدي أي فكرة عن كيفية تجنب هذه الحالات!

وأي شخص أي فكرة عن كيفية حل هذه المشكلة؟

وثنإكس، الغرانيت

هل كانت مفيدة؟

المحلول

وأو استخدام التعابير المنطقية:)

<?php
$str = "Look at this.My score is 3.14, and I am happy about it.";

// alternative to handle Marko's example (updated)
// /([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/

var_dump(preg_split('/([\s\-_,:;?!\/\(\)\[\]{}<>\r\n"]|(?<!\d)\.(?!\d))/',
                    $str, null, PREG_SPLIT_NO_EMPTY));

array(13) {
  [0]=>
  string(4) "Look"
  [1]=>
  string(2) "at"
  [2]=>
  string(4) "this"
  [3]=>
  string(2) "My"
  [4]=>
  string(5) "score"
  [5]=>
  string(2) "is"
  [6]=>
  string(4) "3.14"
  [7]=>
  string(3) "and"
  [8]=>
  string(1) "I"
  [9]=>
  string(2) "am"
  [10]=>
  string(5) "happy"
  [11]=>
  string(5) "about"
  [12]=>
  string(2) "it"
}

نصائح أخرى

ونلقي نظرة على strtok . فإنه يتيح لك تغيير الرموز تحليل حيوي، حتى تتمكن من كسر سلسلة بصرف النظر يدويا في حلقة حين، ودفع كل انشقت كلمة في صفيف.

وكان preg_match_all('/\w+/', $string, $matches); الفكرة الأولى بلدي ولكن هذا يعطي نتيجة مماثلة لتلك التي كنت قد حصلت. المشكلة هي أن أرقام مفصولة نقطة غامضة جدا. ويمكن أن تعني كل من العلامة العشرية ونهاية الجملة لذلك نحن بحاجة إلى وسيلة لتغيير سلسلة في مثل هذه الطريقة للقضاء على معنى مزدوج.

وعلى سبيل المثال في هذه الجملة لدينا العديد من الأجزاء التي نرغب في الاحتفاظ بها كلمة واحدة: "Look at this.My score is 3.14, and I am happy about it. It's not 334,3 and today's not 2009-12-12 11:12:13."

ونبدأ ببناء search-> استبدال القاموس لترميز الاستثناءات إلى شيء لن يحصل انقسام:

$encode = array(
    '/(\d+?)\.(\d+?)/' => '\\1DOT\\2',
    '/(\d+?),(\d+?)/' => '\\1COMMA\\2',
    '/(\d+?)-(\d+?)-(\d+?) (\d+?):(\d+?):(\d+?)/' => '\\1DASH\\2DASH\\3SPACE\\4COLON\\5COLON\\6'
);

وبعد ذلك، نحن ترميز الاستثناءات:

foreach ($encode as $regex => $repl) {
    $string = preg_replace($regex, $repl, $string);
}

وتقسيم سلسلة:

preg_match_all('/\w+/', $string, $matches);

وتحويل كلمة المشفرة مرة أخرى:

$decode = array(
    'search' =>  array('DOT', 'COMMA', 'DASH', 'SPACE', 'COLON'),
    'replace' => array('.',   ',',     '-',    ' ',     ':'    )
);
foreach ($matches as $k => $v) {
    $matches[$k] = str_replace($decode['search'], $decode['replace'], $v);
}

و$matches يحتوي الآن تقسيم الحكم الأصلي في الكلمات مع استثناءات الصحيحة.

ويمكنك جعل التعبير المعتاد استخدامها في استثناءات بسيطة أو معقدة كما تشاء، ولكن بعض الغموض ودائما ما تحصل من خلال، على سبيل المثال اثنين sentances مع أول واحد تنتهي واحدة المقبل بدءا من رقم: Number of the counting shall be 3.3 only and nothing but the 3.5 is right out..

استخدم ". ", بدلا من ".", في $delimiterList.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top