sqlite字母数字混合排序问题

前端之家收集整理的这篇文章主要介绍了sqlite字母数字混合排序问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

字母+数字+。。。+字母+数字

天黑黑223423423423

水电费天往往32423423fdfasf2234234

我飞洒地方3434242sfdkjasfd

12312312321天往往范文芳

。。腐蚀毒粉巍峨3

123213213

等等

当元素任意个时 每个元素长度不确定时 使用sqlite默认排序方式 order by column得到的结果肯定不是你想要的 因为数字排序需要先转换成整形 可以用+1 或者 把charvar转换成int但是这只适合全部为数字时 当字母和数字混合出现时可以用下面的方法来排序

1.用一个标记来区分文本的首字母是字母 还是 汉字 还是 数字 还是 特殊符号(可以是一个字段也可以是个字段的首字母等 这里用字段sort_type表示)在用一个字段(字段的某些字母或一个字段这里用sort_key表示)来记录该文本汉字转换成拼音其他的不变 在用函数来分别排序 第一个字符 第二个字符。。。第n个字符

order by sort_type,LOWER(SUBSTR(sort_key,1,1)),2,3,LOWER(sort_key)

lower把字母变成小写

substr(x,y,z) 截取字符串函数

x被截取的字段值或字符串

y 截取开始位置 相当于指针 正数 从左到又 由1开始 步长为1 负数 从又到左 由-1开始 步长-1 可以欠位但需拿长度补 如字串123 从左到又为(1,3) 从又到左(-3,-2,-1)

z 截取长度 省略代表无穷大 负数 从又到左截取 指针往左偏移截取长度位 如果不足造成欠位 截取实际长度=截取长度-欠位长度 正数从左到又截取 指针不变

例子 如x为123456 (x,0)、 (x,1) 、(x,-6),(x,-100)为123456 (x,1) 为空 x(0,2) 为1 截取长度为2但欠了一位所以长度为1 (x,3)为345 (x,-1)为2 (x,-3)为12

(x,-4) 为 12 (x,-3,-3)和(x,-4)为123 (x,-1)为6 (x,1)为5 (x,-6,6)为123456 (x,-5,5) 为23456 (x,4)为2345

2.用一个标记来区分文本的首字母是字母 还是 汉字 还是 数字 还是 特殊符号(可以是一个字段也可以是个字段的首字母等 这里用字段sort_type表示) 在用一个字段(字段的某些字母或一个字段这里用sort_key表示)来记录该文本汉字转换成拼音 字母 和特殊符号不变 如果是数字 让该数字的ascii码-零的ascii码48+221

order by sort_type,LOWER(sort_key)

匹配类

  1. package cn.com.fetion.util;
  2.  
  3. import java.util.regex.Pattern;
  4.  
  5. /**
  6. *
  7. * 描述: 检查是否匹配工具类<br>
  8. * @Author nailsoul
  9. * @version 1.0
  10. * @since JDK1.5
  11. */
  12. public class MatcherUtil {
  13. /**
  14. * 匹配:Email地址
  15. */
  16. public static final String REGEX_EMAIL = "^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$";
  17. /**
  18. * 匹配:中国移动手机号(GSM + TDSCDMA-G3 + TD-LTE),号段:134(其中134号段中的1349段被分配给“全球星”卫星手机),135,136,137,138,139,147(数据卡号段),150,151,152,157,158,159,182,184,183,187,188
  19. *
  20. * @deprecated <b><font color="red">(有可能携号转网或者又增加新的号段,最后更新:2012-11-10)</font></b><br />
  21. */
  22. @Deprecated
  23. public static final String REGEX_MOBILE_NUMBER_CHINA_MOBILE = "^1(34[0-8]|(3[5-9]|47|5[012789]|8[23478])\\d)\\d{7}$";
  24. /**
  25. * 匹配:中国联通手机号(GSM + WCDMA-沃),号段:130,131,132,145(数据卡号段),155,156,185,186
  26. *
  27. * @deprecated <b><font color="red">(有可能携号转网或者又增加新的号段,最后更新:2012-11-10)</font></b><br />
  28. */
  29. @Deprecated
  30. public static final String REGEX_MOBILE_NUMBER_CHINA_UNICOM = "^1(3[0-2]|45|5[56]|8[56])\\d{8}$";
  31. /**
  32. * 匹配:中国电信手机号(CDMA + CDMA2000-天翼),号段:133,1349(卫星通信,原中国卫通),153,180,181,189
  33. *
  34. * @deprecated <b><font color="red">(有可能携号转网或者又增加新的号段,最后更新:2012-11-10)</font></b><br />
  35. * "^1(3[3]|45|5[3]|8[019])\\d{8}$"
  36. */
  37. @Deprecated
  38. public static final String REGEX_MOBILE_NUMBER_CHINA_TELECOM = "^1(33[0-9]|349|(5[3]|8[019])\\d)\\d{7}$";
  39. /**
  40. * 匹配:手机号码
  41. */
  42. public static final String REGEX_MOBILE_NUMBER = "^[1][3-8]+\\d{9}$";
  43.  
  44. /**
  45. * 正则表达式中使用的特殊的计算符号,如:'$','*',...
  46. */
  47. public static final char[] PATTERN_REGEX_SPECIAL_CHARACTERS = { '$',// 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。
  48. '(',')',// 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
  49. '*',// 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
  50. '+',// 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
  51. '.',// 匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。
  52. '[',// 标记一个中括号表达式的开始。要匹配 [,请使用 \[。
  53. '?',// 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
  54. '\\',// 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。
  55. '^',// 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。
  56. '{',// 标记限定符表达式的开始。要匹配 {,请使用 \{。
  57. '|',// 指明两项之间的一个选择。要匹配 |,请使用 \|。
  58. };
  59.  
  60. /** 数字 */
  61. private static final int TYPE_DIGIT = 1;
  62. /** 小写字母字符 */
  63. private static final int TYPE_LOWER_LETTER = 2;
  64. /** 大写字母字符 */
  65. private static final int TYPE_UPPER_LETTER = 3;
  66. /** 汉字字符串包括中文标点符号 */
  67. private static final int TYPE_CJK = 4;
  68. /** 汉字字符串剔除了中文标点符号 */
  69. private static final int TYPE_NO_PUNCTUATION_CJK = 5;
  70. /** 是否是空白字符 */
  71. private static final int TYPE_WHITESPACE = 6;
  72.  
  73. private static boolean isMatchesChar(int type,char ch) {
  74. switch (type) {
  75. case TYPE_DIGIT:
  76. return Character.isDigit(ch);
  77. case TYPE_LOWER_LETTER:
  78. return isLowerLetter(ch);
  79. case TYPE_UPPER_LETTER:
  80. return isUpperLetter(ch);
  81. case TYPE_CJK:
  82. return isCJK(ch);
  83. case TYPE_NO_PUNCTUATION_CJK:
  84. return isNoPunctuationCJK(ch);
  85. case TYPE_WHITESPACE:
  86. return Character.isWhitespace(ch);
  87. default:
  88. return false;
  89. }
  90. }
  91.  
  92. private static boolean isMatches(int type,String input) {
  93. if (input != null && input.length() > 0) {
  94. for (int i = input.length() - 1; i >= 0; i--) {
  95. if (!isMatchesChar(type,input.charAt(i))) {
  96. return false;
  97. } else if (i == 0) {
  98. return true;
  99. }
  100. }
  101. }
  102. return false;
  103. }
  104.  
  105. private static boolean isMatchesInclude(int type,String input) {
  106. if (input != null && input.length() > 0) {
  107. for (int i = input.length() - 1; i >= 0; i--) {
  108. if (isMatchesChar(type,input.charAt(i))) {
  109. return true;
  110. }
  111. }
  112. }
  113. return false;
  114. }
  115.  
  116. /**
  117. * 匹配正则表达式
  118. *
  119. * @param regex
  120. * @param input
  121. * @return
  122. */
  123. public static boolean isMatches(String regex,String input) {
  124. return input == null ? false : Pattern.compile(regex).matcher(input).find();
  125. }
  126.  
  127. /**
  128. * 匹配正则表达式(忽略大小写)
  129. *
  130. * @param regex
  131. * @param input
  132. * @return
  133. */
  134. public static boolean isMatchesIgnoreCase(String regex,String input) {
  135. return input == null ? false : Pattern.compile(regex,Pattern.CASE_INSENSITIVE).matcher(input).find();
  136. }
  137.  
  138. /**
  139. * 是否是正则表达式中使用的特殊的计算符号,如:'$',...
  140. *
  141. * @param ch
  142. * @return
  143. */
  144. public static boolean isPatternRegexSpecialCharacter(char ch) {
  145. for (int i = PATTERN_REGEX_SPECIAL_CHARACTERS.length - 1; i >= 0; i--) {
  146. if (ch == PATTERN_REGEX_SPECIAL_CHARACTERS[i]) {
  147. return true;
  148. }
  149. }
  150. return false;
  151. }
  152.  
  153.  
  154.  
  155. /**
  156. * 是否是数字字符串
  157. *
  158. * @param input
  159. * @return
  160. */
  161. public static boolean isDigit(String input) {
  162. return isMatches(TYPE_DIGIT,input);
  163. }
  164.  
  165. /**
  166. * 是否包含数字字符串
  167. *
  168. * @param input
  169. * @return
  170. */
  171. public static boolean isIncludeDigit(String input) {
  172. return isMatchesInclude(TYPE_DIGIT,input);
  173. }
  174.  
  175. /**
  176. * 是否是小写字母字符([a-z])
  177. *
  178. * @param ch
  179. * @return
  180. */
  181. public static boolean isLowerLetter(char ch) {
  182. return ch >= 0x61 && ch <= 0x7A;
  183. }
  184.  
  185. /**
  186. * 是否是小写字母字符串([a-z])
  187. *
  188. * @param input
  189. * @return
  190. */
  191. public static boolean isLowerLetter(String input) {
  192. return isMatches(TYPE_LOWER_LETTER,input);
  193. }
  194.  
  195. /**
  196. * 是否包含小写字母字符串([a-z])
  197. *
  198. * @param input
  199. * @return
  200. */
  201. public static boolean isIncludeLowerLetter(String input) {
  202. return isMatchesInclude(TYPE_LOWER_LETTER,input);
  203. }
  204.  
  205. /**
  206. * 是否是大写字母字符([A-Z])
  207. *
  208. * @param ch
  209. * @return
  210. */
  211. public static boolean isUpperLetter(char ch) {
  212. return ch >= 0x41 && ch <= 0x5A;
  213. }
  214.  
  215. /**
  216. * 是否是大写字母字符串([A-Z])
  217. *
  218. * @param ch
  219. * @return
  220. */
  221. public static boolean isUpperLetter(String input) {
  222. return isMatches(TYPE_UPPER_LETTER,input);
  223. }
  224.  
  225. /**
  226. * 是否包含大写字母字符串([A-Z])
  227. *
  228. * @param input
  229. * @return
  230. */
  231. public static boolean isIncludeUpperLetter(String input) {
  232. return isMatchesInclude(TYPE_UPPER_LETTER,input);
  233. }
  234.  
  235. /**
  236. * 是否是字母字符串([A-Za-z])
  237. *
  238. * @param ch
  239. * @return
  240. */
  241. public static boolean isLetter(char ch) {
  242. return isLowerLetter(ch) || isUpperLetter(ch);
  243. }
  244.  
  245. /**
  246. * 是否是汉字字符(广义上的汉字字符,很多都无法用输入法输出的汉字)
  247. *
  248. * @param c
  249. * @return
  250. */
  251. public static boolean isCJK(char c) {
  252. Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
  253. if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS // CJK统一汉字 \\u4E00-\\u9fAF
  254. || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A // CJK统一汉字扩展-A \\u3400-\\u4dBF
  255. || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS // CJK兼容汉字 \\uF900-\\uFAFF
  256. || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION // CJK符号和标点 \\u3000-\\u303F
  257. || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION // 广义标点 \\u2000-\\u206F
  258. || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { // 半形及全形字符 \\uFF00-\\uFFEF
  259. return true;
  260. }
  261. return false;
  262. }
  263.  
  264. /**
  265. * 是否是汉字字符(不包含标点)
  266. *
  267. * @param c
  268. * @return
  269. */
  270. public static boolean isNoPunctuationCJK(char c) {
  271. Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
  272. if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS // CJK统一汉字 \\u4E00-\\u9fAF
  273. || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A // CJK统一汉字扩展-A \\u3400-\\u4dBF
  274. || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS) { // CJK兼容汉字 \\uF900-\\uFAFF
  275. return true;
  276. }
  277. return false;
  278. }
  279.  
  280. /**
  281. * 是否是汉字字符(不包含标点)
  282. *
  283. * @param c
  284. * @return
  285. */
  286. public static boolean isNoPunctuationCJK(String input) {
  287. return isMatches(TYPE_NO_PUNCTUATION_CJK,input);
  288. }
  289.  
  290. /**
  291. * 是否是汉字字符串(广义上的汉字字符,很多都无法用输入法输出的汉字)
  292. *
  293. * @param input
  294. * @return
  295. */
  296. public static boolean isCJK(String input) {
  297. return isMatches(TYPE_CJK,input);
  298. }
  299.  
  300. /**
  301. * 是否包含汉字字符串(广义上的汉字字符,很多都无法用输入法输出的汉字)
  302. *
  303. * @param input
  304. * @return
  305. */
  306. public static boolean isIncludeCJK(String input) {
  307. return isMatchesInclude(TYPE_CJK,input);
  308. }
  309.  
  310. /**
  311. * 是否是空白字符
  312. *
  313. * @param input
  314. * @return
  315. */
  316. public static boolean isWhitespace(String input) {
  317. return isMatches(TYPE_WHITESPACE,input);
  318. }
  319.  
  320. /**
  321. * 是否包含空白字符
  322. *
  323. * @param input
  324. * @return
  325. */
  326. public static boolean isIncludeWhitespace(String input) {
  327. return isMatchesInclude(TYPE_WHITESPACE,input);
  328. }
  329.  
  330. }

更具文本生产用来排序的字段



  1. /**
  2. * 此接口定义了排序规则中最基本的字段,子类用哪些字段排序由子类自己决定, 以下是目前的规则(优先级高的放在前面) 1.群组排序字段:状态、群组名称 2.讨论组排序字段:论组名称 3.好友排序字段:备注、昵称、电话号码、飞信号(此好友只联系人列表好友、讨论组成员列表、群组成员列表)
  3. */
  4. public interface BaseSortColumns extends BaseColumns {
  5. /** 是否全是数字或者特殊字符或者生僻字 0 正常 1 不正常 */
  6. public static final String SPECIAL_CHARACTERS = "special_characters";
  7. /** 英文、中文、中英文规则;全部英文为1,中英混合为2 ,全部中文为100 */
  8. public static final String ENGLISH_CHINESE_ORDER = "english_chinese_order";
  9. /** 好友排序key */
  10. public static final String SORT_KEY = "sort_key";
  11. /** 此好友是否置顶,1代表是,0代表否 */
  12. public static final String IS_TOP = "is_top";
  13. }
  14.  
  15. public class BaseSort implements BaseSortColumns {
  16. /**
  17. * 不全是数字和字符
  18. * */
  19. public static final int TYPE_NAME_NORMAL = 0;
  20. /**
  21. * 全是数字或特殊字符
  22. * */
  23. public static final int TYPE_NAME_UNNORMAL = 1;
  24. /**
  25. * 全是英文
  26. * */
  27. public static final int TYPE_ENGLISH_ALL = 2;
  28. /**
  29. * 全是汉字
  30. * */
  31. public static final int TYPE_CHINESE_ALL = 3;
  32. /**
  33. * 全是数字
  34. * */
  35. public static final int TYPE_NUMBER_ALL = 4;
  36. /**
  37. * 全特殊字符
  38. */
  39. public static final int TYPE_SPECIAL_ALL = 5;
  40. }
  41.  
  42. /**
  43. * 从sortColumns中选择用来排序的字段,sortColumns要中排在前面的优先级高
  44. *
  45. * @param contentValues
  46. * @param sortColumns
  47. */
  48. public static void SetBaseSortKey(ContentValues contentValues,String[] sortColumns) {
  49. if (null == sortColumns || sortColumns.length <= 0 || null == contentValues || contentValues.size() <= 0) {
  50. return;
  51. }
  52. String sortKey = null;
  53. for (int i = 0; i < sortColumns.length; i++) {
  54. sortKey = contentValues.getAsString(sortColumns[i]);
  55. if (!TextUtils.isEmpty(sortKey) && sortKey.trim().length() > 0) {
  56. break;
  57. }
  58. }
  59. StringBuilder builder = new StringBuilder();
  60. for (int i = 0; i < sortColumns.length; i++) {
  61. builder.append("sort column:").append(sortColumns[i]).append(" column value:").append(contentValues.getAsString(sortColumns[i]));
  62. }
  63. LogF.d(RESET_TAG,"---resetContactValues,sortKey = " + builder.toString());
  64. parseAndInsertBaseSortKey(contentValues,sortKey);
  65. }
  66.  
  67. /**
  68. * 解析sortkey,保存到BaseSortColumn.SortKey中
  69. *
  70. * @param contentValues
  71. * @param sortColumns
  72. */
  73. private static void parseAndInsertBaseSortKey(ContentValues contentValues,String sortKey) {
  74. if (!TextUtils.isEmpty(sortKey)) {
  75. String pinyins = null;
  76. char firstChar = sortKey.charAt(0);
  77. if (MatcherUtil.isLetter(firstChar)) {
  78. contentValues.put(BaseSortColumns.SPECIAL_CHARACTERS,BaseSort.TYPE_NAME_NORMAL);
  79. contentValues.put(BaseSortColumns.ENGLISH_CHINESE_ORDER,BaseSort.TYPE_ENGLISH_ALL);
  80. if (MatcherUtil.isIncludeCJK(sortKey)) {
  81. pinyins = PinyinHelper.getInstance().getPinyins(sortKey," ");
  82. }
  83. LogF.d(TAG,"resetContactValues.sortKey = " + sortKey + ",firstChar is letter" + (pinyins == null ? "" : ",pinyins = " + pinyins));
  84. } else if (MatcherUtil.isDigit(String.valueOf(firstChar))) {
  85. contentValues.put(BaseSortColumns.SPECIAL_CHARACTERS,BaseSort.TYPE_NAME_UNNORMAL);
  86. contentValues.put(BaseSortColumns.ENGLISH_CHINESE_ORDER,BaseSort.TYPE_NUMBER_ALL);
  87. if (MatcherUtil.isIncludeCJK(sortKey)) {
  88. pinyins = PinyinHelper.getInstance().getPinyins(sortKey,firstChar is digit" + (pinyins == null ? "" : ",pinyins = " + pinyins));
  89. } else if (MatcherUtil.isNoPunctuationCJK(firstChar)) {
  90. contentValues.put(BaseSortColumns.SPECIAL_CHARACTERS,BaseSort.TYPE_CHINESE_ALL);
  91. pinyins = PinyinHelper.getInstance().getPinyins(sortKey," ");
  92. LogF.d(TAG,firstChar is cjk,pinyins = " + pinyins);
  93. } else {
  94. if (MatcherUtil.isIncludeCJK(sortKey)) {
  95. pinyins = PinyinHelper.getInstance().getPinyins(sortKey," ");
  96. }
  97. contentValues.put(BaseSortColumns.SPECIAL_CHARACTERS,BaseSort.TYPE_SPECIAL_ALL);
  98. }
  99. sortKey=TextUtils.isEmpty(pinyins) ? sortKey : pinyins;
  100. StringBuffer sb=new StringBuffer();
  101. char tmpChar=1;
  102. for(int index=0;index<sortKey.length();index++){
  103. tmpChar=sortKey.charAt(index);
  104. if(Character.isDigit(tmpChar)){
  105. tmpChar = (char) (tmpChar - ASCII_ZERO + ASCII_CUSTOM_NUMBER_FIRST);
  106. }
  107. sb.append(tmpChar);
  108. }
  109. contentValues.put(BaseSortColumns.SORT_KEY,sb.toString());
  110. }
  111. }

猜你在找的Sqlite相关文章