单条短信长度有限制,为64或60个字符,尾部预留6个公司标识([XXXX]),如果短信内容超长这个限制,需要分拆成两条或多条。实际应用中碰到一个问题,运用定长拆分时,一个完整的数字可能被截断,造成短信阅读困难。所以需要用程序加以控制,如下面的净值短信需要拆分,数值部分可能需要新起一条短信。
7月9日净值:成长1.4394增长3.761稳健1.039债券1.190服务3.414保本1 .553超短债1.0026主题1.562策略1.354沪深三百1.491货币基金万份收益0.6250元,七日年化收益率5.720%,
将被拆分为:
7月9日净值:成长1.4394增长3.761稳健1.039债券1.190服务3.414保本1 .553超短债1.0026主题
1.562策略1.354沪深三百1.491货币基金万份收益0.6250元,七日年化收益率5.720%
程序逻辑比较简单,就是寻找短信切分位置,先将指针置到单条短信最大长度处(如第64个字符处),然后判断是否需要回溯,若刚好落在一个完整的数值中时,需要回溯指针到非数字字符上。切分位置确定后,即可进行字符串分割操作。需要注意的是'.‘小数点的处理。附上参考程序,希冀能抛砖引玉
附,存储过程(oracle9i,pl/sql代码)
--CREATE PROCEDURE p_split_sms AS
declare
smscontent VARCHAR2(2000); -- 剩余短信内容
smspart VARCHAR2(100); -- 分拆后单条短信
len INTEGER; -- 剩余短信内容长度
pos INTEGER; -- 短信分拆位置
n INTEGER; -- pos位置的字符ASCII码
n1 INTEGER; -- pos+1位置的字符ASCII码
n2 INTEGER; -- pos+2位置的字符ASCII码
MAXLEN INTEGER := 64; -- 最大短信长度
begin
-- Test statements here
smscontent := '6月22日净值:成长1.4691增长3.91稳健1.092债券1.201服务3.544保本1.567超短债1.0033主题1.869策略1.459沪深三百1.576货币基金万份收益1.8759元,七日年化收益率7.475%';
len := length(smscontent);
-- 短信内容是否需要拆分成多条
WHILE len > MAXLEN LOOP
pos := MAXLEN; -- 短信拆分位置
n := ascii(substr(smscontent, pos, 1));
n1 := ascii(substr(smscontent, pos + 1, 1));
n2 := ascii(substr(smscontent, pos + 2, 1)); -- 可能返回NULL值(指针越界)
-- ...主题1.869策略...(充分考虑pos指针位置,即位于数值任意位置时的相应处理)
-- 下一个字符为数字,或后两字符为小数点+数字形式('5', '.5')
-- ASCII: [0-9]~[48-57], '.'~46
IF ((n1 >= 48 AND n1 <= 57) OR (n1 = 46 AND (n2 >= 48 AND n2 <= 57))) THEN
-- 回溯至第一个非[0-9.]的字符所在位置
WHILE (pos > 0 AND (n >= 48 AND n <= 57) OR n = 46) LOOP -- 匹配[0-9.]
pos := pos - 1;
n := ascii(substr(smscontent, pos, 1));
END LOOP;
END IF;
-- 若数字部分超长,则不考虑数值显示完整性(即无需另起一行)
IF pos < (MAXLEN / 2) THEN
pos := MAXLEN;
END IF;
smspart := substr(smscontent, 1, pos);
smscontent := substr(smscontent, pos + 1);
len := length(smscontent);
dbms_output.put_line(smspart);
END LOOP;
IF (len IS NOT NULL) THEN
-- 最后剩余部分,长度不足MAXLEN
dbms_output.put_line(smscontent);
END IF;
end;