我需要一种算法(最好是在Python中)将任意字符串转换为仅包含GSM字母表中字符的字符串。我需要这个过滤器将字符串作为文本发送到SMS:es。如果可能,算法还应该用最接近的可编码等效替换字符。例子:
>>> gsm_convert('© all rights reserved')
[copyright sign] all rights reserved
# or
C all rights reserved
>>> gsm_convert('––– long dashes –––')
--- long dashes ---
Python有一些内置算法可以做到这一点,但这些函数也将输入字符串转换为不正确的ascii。 GSM处理ascii中没有的几个字符。
答案 0 :(得分:4)
从在Perl和PHP中执行此操作,我将使用正则表达式分两步完成。
首先包括正则表达式支持
import re
用最接近的匹配替换任何你可以使用的字符。
我建议使用一组正则表达式,例如使用以下
将“á”替换为“a”message = ur'abc\u00e9\u00e1'
message = re.sub(ur'\u00e1','a',message)
删除任何不在GSM字符集中的剩余字符。
message = ur'abc\u00e9\u00e1'
message = re.sub(ur'[^\u0040\u00A3\u0024\u00A5\u00E8\u00E9\u00F9\u00EC\u00F2\u00C7\u000A\u00D8\u00F8\u000D\u00C5\u00E5\u0394\u005F\u03A6\u0393\u039B\u03A9\u03A0\u03A8\u03A3\u0398\u039E\u00C6\u00E6\u00DF\u00C9\u0020\u0021\u0022\u0023\u00A4\u0025\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u002D\u002E\u002F\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003A\u003B\u003C\u003D\u003E\u003F\u00A1\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004A\u004B\u004C\u004D\u004E\u004F\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005A\u00C4\u00D6\u00D1\u00DC\u00A7\u00BF\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006A\u006B\u006C\u006D\u006E\u006F\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007A\u00E4\u00F6\u00F1\u00FC\u00E0\u20AC\u005B\u005C\u005D\u005E\u007B\u007C\u007D\u007E]','',message)
print message
在此示例中,它将打印abcé
,删除不属于GSM字符集的á
(\u00e1
)。
答案 1 :(得分:1)
听起来你需要一个编解码器。谷歌搜索出现了这个:http://demo.sahanafoundation.org/gsoc2010/amishra/gsoc/modules/pygsm/gsmcodecs/ 我不知道它是否有效,你必须自己找出来。
该代码的许可证位于http://demo.sahanafoundation.org/gsoc2010/amishra/gsoc/modules/pygsm/LICENSE
编辑:嗨,这里是pygsm的贡献者(如果有任何疑问,请在docstring测试中调用该数字)。
仅供参考 - 上面链接的Sahana代码似乎已移至:http://eden.sahanafoundation.org/browser#modules/pygsm/
此外,此Sahana代码源自https://github.com/developmentseed/slingshotSMS,源自原始的独立库https://github.com/adammck/pygsm/ ...其许可证位于https://raw.github.com/adammck/pygsm/master/LICENSE
答案 2 :(得分:0)
第一个响应中的链接看起来可能会起作用; FWIW,我使用了从this post链接的库作为做类似事情的基础。
正如您将看到的,作者已经创建了一个适合编码希腊语的编解码器,所以这只是一个起点。
你说你想将“任意”字符串转换为“最接近的等价物”;使它完全随意可能很困难,因为“最接近”可能在不同的域中具有不同的含义(例如,你如何处理Unicode雪人)?
如果你只是想处理拉丁语或拉丁语衍生的字母表,那么“任意”应该是可行的。
答案 3 :(得分:0)
这是我的C#代码(法语)
public static bool IsGsmString(string message)
{
// https://messente.com/documentation/tools/sms-length-calculator
// https://stackoverflow.com/questions/29541753/regex-only-checks-first-character-in-string-c-sharp/29541980#29541977
//var strMap = new Regex(@"^[@£$¥èéùìòÇØøÅå_ÆæßÉ!""#%&'()*+,./\w:;<=>? ¡ÄÖÑܧ¿äöñüà^{}\[~\]|€-]*$");
//return !strMap.IsMatch(message.Replace(Environment.NewLine, "")); // Enlever les saut de ligne car non inclus dans le Map
foreach (char c in message.ToCharArray())
if (!IsGsmChar(c))
return false;
return true;
}
public static bool IsGsmChar(char c)
{
string strGSMTable = "@£$¥èéùìòÇ`Øø`ÅåΔ_ΦΓΛΩΠΨΣΘΞ`ÆæßÉ !\"#¤%&'()*=,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑÜ`¿abcdefghijklmnopqrstuvwxyzäöñüà";
strGSMTable += "^{}\\[~]|€" + Environment.NewLine; // Adding extended char and CRLF
return strGSMTable.IndexOf(c) >= 0;
}
public static string ReplaceNoneGsmChar(string message)
{
var converted = "";
foreach (char c in message.ToCharArray())
{
if (IsGsmChar(c))
converted += c;
else
converted += GsmReplacement(c);
}
return converted;
}
private static string GsmReplacement(char c)
{
switch (c)
{
case 'â':
return "a";
case 'ê':
case 'ë':
return "e";
case 'î':
case 'ï':
return "i";
case 'ô':
return "o";
case 'û':
return "u";
case 'ÿ':
return "y";
case 'Â':
case 'À':
return "A";
case 'È':
case 'Ê':
case 'Ë':
return "E";
case 'Î':
case 'Ï':
case 'Ì':
return "I";
case 'Ô':
return "I";
case 'Ù':
case 'Û':
return "U";
case '’':
case '`':
return "'";
case '«':
case '»':
return @"""";
case 'µ':
return "u";
case '©':
return "C";
case 'œ':
return "oe";
default:
return "_"; // non remplacable
}
}