2013-11-24 2 views
1

대용량 메시지를 보낼 수 있도록 160 자 이상의 SMS 메시지를 여러 부분으로 분할해야합니다."이스케이프 처리 된 charatcers"가 포함 된 SMS 메시지 분할

일부 SMS API는 분할을 처리하지만 (여러 부분으로 구성된 메시지를 지원함) 두 회사와 협력하여 메시지를 나눠야합니다.

메시지 나누기가 쉽습니다. 내 문제는 SMS 메시지에 "이스케이프 처리"및 "사용량 초과"문자가 포함 된 경우 어떻게해야합니까? 그들은 "최대 사용"이 개 문자를 의미합니다, 몇 문자 "탈출"하여도 7 비트 인코딩으로

: 내가 무슨 말을하고 무슨 생각이없는 사람들을 위해

. 기본 7 비트 인코딩에서 이들은 {}[]\|^~€입니다.

출처 :

이 지불 금액은 € 100 : https://stackoverflow.com/a/7061794/158126

그래서 예를 들어,이 문자열이 긴 35 자입니다. SMS 공급자를 통해 보낼 때

그러나, 실제로 때문에 "탈출"이고 두 개의 문자를 차지하는 유로 기호의36 자입니다.

SMS 메시지를 분할하는 데는 여러 가지 질문이 있지만이 중 일부는 "이스케이프 처리 된"문자로 인해 문제가 발생할 수 있다는 사실을 고려하지 않았습니다.

그래서이 문제를 해결할 수있는 함수를 만들었습니다. 나는 이것을 시험해 보았고, 다른 사람을 도울 수 있기를 바랍니다.

제 질문으로 돌아가려면 코드가 매우 비효율적이라고 생각합니다. 나는 루프 내에서 preg_match을 여러 번 실행하고 있으며 더 나은 솔루션을 확신하지 못합니다.

누구든지이 코드를보다 효율적으로 만들 수있는 방법에 대한 제안 사항이 있습니까?

function sms_message_parts($message) { 

    // Message parts 
    $parts = array(); 

    // The default encoding is utf16 (unicode) until proven otherwise 
    $encoding = 'utf16'; 

    // Characters that are allowed in 7bit messages 
    $gsm_7bit_chars = '@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&\'\(\)\*+,-\.\/:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà'; 

    // Characters that are allowed in 7bit_ex messages 
    $gsm_7bit_ex_chars = '\^{}\\\\\[~\]|€'; 

    // Message lengths 
    $message_lengths = array(
     '7bit' => 160, 
     '7bit_ex' => 160, 
     'utf16' => 70 
    ); 

    // Detect encoding of message 
    if (preg_match("/^[" . $gsm_7bit_chars . "]*$/u", $message) == 1) 
     $encoding = '7bit'; 
    elseif (preg_match("/^[" . $gsm_7bit_chars . $gsm_7bit_ex_chars . "]*$/u", $message) == 1) 
     $encoding = '7bit_ex'; 

    // Determine how long each part of the message can be 
    $max_parts_length = $message_lengths[$encoding]; 

    // Length of the message 
    $message_length = mb_strlen($message, 'UTF-8'); 

    // 7bit_ex message 
    // Escaped characters found so we need to find the REAL length 
    // and split the message differently 
    if ($encoding == '7bit_ex') { 

     // Count how many extra characters are required a result of 
     // the 7bit_ex characters 
     $extra_chars = 0; 
     for($i=0;$i<$message_length;$i++) { 
      if (preg_match("/^[" . $gsm_7bit_ex_chars . "]*$/u", mb_substr($message, $i, 1, 'UTF-8')) == 1) 
       $extra_chars++; 
     } 

     // New message length 
     $new_message_length = $message_length + $extra_chars; 

     // Is this going to be a multipart message? 
     if ($new_message_length > $max_parts_length) { 

      // Split the message 
      $start = 0; 
      while(true) { 

       // Determine the length of the split (if it's the last part, we don't need to look for 
       // extra "escaped" characters) 
       $last_part = false; 
       $chars_left = $message_length - $start; 
       if ($chars_left < $max_parts_length) { 
        $split_length = $chars_left; 
        $last_part = true; 
       } else { 
        $split_length = $max_parts_length; 
       } 

       // Extract the message part 
       $part = mb_substr($message, $start, $split_length, 'UTF-8'); 

       // Check to see if this part has any escaped characters 
       $part_extra_chars = 0; 
       if (!$last_part) { 
        for($i=0;$i<$split_length;$i++) { 
         if (preg_match("/^[" . $gsm_7bit_ex_chars . "]*$/u", mb_substr($part, $i, 1, 'UTF-8')) == 1) 
          $part_extra_chars++; 
        } 
       } 

       // If it has escaped characters, deduct from the amount of characters in this part 
       // before adding to the parts array 
       if ($part_extra_chars > 0) { 

        $part = mb_substr($message, $start, ($split_length - $part_extra_chars), 'UTF-8'); 
        $parts[] = trim($part); 
        $start = $start + ($split_length - $part_extra_chars); 

       // No escaped characters, add part to parts array 
       } else { 

        $parts[] = trim($part) . ' ' .$split_length; 
        $start = $start + $max_parts_length; 

       } 

       // We've reached the end of the message 
       if ($start >= $message_length) 
        break; 

      } 

     // It's a signle message 
     } else { 
      $parts[] = $message; 
     } 

    // 7bit and utf16 (unicode) messages don't have escaped characters 
    } else { 

     // Is this going to be a multipart message? Split this part before adding to the 
     // parts array 
     if ($message_length > $max_parts_length) { 

      // Split the message into parts 
      $total_messages = ceil($message_length/$max_parts_length); 
      $start = 0; 
      for($i=0;$i<$total_messages;$i++) { 
       $parts[] = trim(mb_substr($message, $start, $max_parts_length, 'UTF-8')); 
       $start = $start + $max_parts_length; 
      } 

     // It's a signle message 
     } else { 
      $parts[] = $message; 
     } 

    } 

    return array('parts' => $parts, 'encoding' => $encoding); 

} 

답변

0

특정 charcater를 건너 뛰고 싶다면 regex를 사용할 수 있습니다. 같은

뭔가 (? # 등) 사이 (?#comment)

모든 것은 정규식 엔진에 의해 무시됩니다.

아니면 어떠한 문자로 원하는 문자를 대체 할 수있는 당신은 replace_all와 정규식을 사용할 수 있습니다 즉 ''

관련 문제