sqlite字母数字混合排序问题

sqlite字母数字混合排序问题,第1张

概述字母+数字+。。。+字母+数字 天黑黑223423423423 水电费天往往32423423fdfasf2234234 我飞洒地方3434242sfdkjasfd 12312312321天往往范文芳 。。腐蚀毒粉巍峨3 123213213 等等 当元素任意个时  每个元素长度不确定时  使用sqlite默认排序方式  order by column得到的结果肯定不是你想要的    因为数字排序需要

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

天黑黑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)

匹配类

package cn.com.fetion.util;import java.util.regex.Pattern;/** * * 描述: 检查是否匹配工具类<br> * @Author nailsoul * @version 1.0 * @since JDK1.5 */public class MatcherUtil {	/**	 * 匹配:Email地址	 */	public static final String REGEX_EMAIL = "^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$";	/**	 * 匹配:中国移动手机号(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	 * 	 * @deprecated <b><Font color="red">(有可能携号转网或者又增加新的号段,最后更新:2012-11-10)</Font></b><br />	 */	@Deprecated	public static final String REGEX_MOBILE_NUMBER_CHINA_MOBILE = "^1(34[0-8]|(3[5-9]|47|5[012789]|8[23478])\d)\d{7}$";	/**	 * 匹配:中国联通手机号(GSM + WCDMA-沃),号段:130,131,132,145(数据卡号段),155,156,185,186	 * 	 * @deprecated <b><Font color="red">(有可能携号转网或者又增加新的号段,最后更新:2012-11-10)</Font></b><br />	 */	@Deprecated	public static final String REGEX_MOBILE_NUMBER_CHINA_UNICOM = "^1(3[0-2]|45|5[56]|8[56])\d{8}$";	/**	 * 匹配:中国电信手机号(CDMA + CDMA2000-天翼),号段:133,1349(卫星通信,原中国卫通),153,180,181,189	 * 	 * @deprecated <b><Font color="red">(有可能携号转网或者又增加新的号段,最后更新:2012-11-10)</Font></b><br />	 *             "^1(3[3]|45|5[3]|8[019])\d{8}$"	 */	@Deprecated	public static final String REGEX_MOBILE_NUMBER_CHINA_TELECOM = "^1(33[0-9]|349|(5[3]|8[019])\d)\d{7}$";	/**	 * 匹配:手机号码	 */	public static final String REGEX_MOBILE_NUMBER = "^[1][3-8]+\d{9}$";	/**	 * 正则表达式中使用的特殊的计算符号,如:'$','*',...	 */	public static final char[] PATTERN_REGEX_SPECIAL_CHaraCTERS = { '$',// 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 $。			'(',')',// 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。			'*',// 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。			'+',// 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。			'.',// 匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。			'[',// 标记一个中括号表达式的开始。要匹配 [,请使用 \[。			'?',// 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。			'\',// 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\' 匹配 "\",而 '\(' 则匹配 "("。			'^',// 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。			'{',// 标记限定符表达式的开始。要匹配 {,请使用 \{。			'|',// 指明两项之间的一个选择。要匹配 |,请使用 \|。	};	/** 数字 */	private static final int TYPE_DIGIT = 1;	/** 小写字母字符 */	private static final int TYPE_LOWER_LETTER = 2;	/** 大写字母字符 */	private static final int TYPE_UPPER_LETTER = 3;	/** 汉字字符串包括了中文标点符号 */	private static final int TYPE_CJK = 4;	/** 汉字字符串剔除了中文标点符号 */	private static final int TYPE_NO_PUNCTUATION_CJK = 5;	/** 是否是空白字符 */	private static final int TYPE_WHITESPACE = 6;	private static boolean isMatchesChar(int type,char ch) {		switch (type) {			case TYPE_DIGIT:				return Character.isDigit(ch);			case TYPE_LOWER_LETTER:				return isLowerLetter(ch);			case TYPE_UPPER_LETTER:				return isUpperLetter(ch);			case TYPE_CJK:				return isCJK(ch);			case TYPE_NO_PUNCTUATION_CJK:				return isnopunctuationCJK(ch);			case TYPE_WHITESPACE:				return Character.isWhitespace(ch);			default:				return false;		}	}	private static boolean isMatches(int type,String input) {		if (input != null && input.length() > 0) {			for (int i = input.length() - 1; i >= 0; i--) {				if (!isMatchesChar(type,input.charat(i))) {					return false;				} else if (i == 0) {					return true;				}			}		}		return false;	}	private static boolean isMatchesInclude(int type,String input) {		if (input != null && input.length() > 0) {			for (int i = input.length() - 1; i >= 0; i--) {				if (isMatchesChar(type,input.charat(i))) {					return true;				}			}		}		return false;	}	/**	 * 匹配正则表达式	 * 	 * @param regex	 * @param input	 * @return	 */	public static boolean isMatches(String regex,String input) {		return input == null ? false : Pattern.compile(regex).matcher(input).find();	}	/**	 * 匹配正则表达式(忽略大小写)	 * 	 * @param regex	 * @param input	 * @return	 */	public static boolean isMatchesIgnoreCase(String regex,String input) {		return input == null ? false : Pattern.compile(regex,Pattern.CASE_INSENSITIVE).matcher(input).find();	}	/**	 * 是否是正则表达式中使用的特殊的计算符号,如:'$',...	 * 	 * @param ch	 * @return	 */	public static boolean isPatternRegexSpecialCharacter(char ch) {		for (int i = PATTERN_REGEX_SPECIAL_CHaraCTERS.length - 1; i >= 0; i--) {			if (ch == PATTERN_REGEX_SPECIAL_CHaraCTERS[i]) {				return true;			}		}		return false;	}	/**	 * 是否是数字字符串	 * 	 * @param input	 * @return	 */	public static boolean isDigit(String input) {		return isMatches(TYPE_DIGIT,input);	}	/**	 * 是否包含数字字符串	 * 	 * @param input	 * @return	 */	public static boolean isIncludeDigit(String input) {		return isMatchesInclude(TYPE_DIGIT,input);	}	/**	 * 是否是小写字母字符([a-z])	 * 	 * @param ch	 * @return	 */	public static boolean isLowerLetter(char ch) {		return ch >= 0x61 && ch <= 0x7A;	}	/**	 * 是否是小写字母字符串([a-z])	 * 	 * @param input	 * @return	 */	public static boolean isLowerLetter(String input) {		return isMatches(TYPE_LOWER_LETTER,input);	}	/**	 * 是否包含小写字母字符串([a-z])	 * 	 * @param input	 * @return	 */	public static boolean isIncludeLowerLetter(String input) {		return isMatchesInclude(TYPE_LOWER_LETTER,input);	}	/**	 * 是否是大写字母字符([A-Z])	 * 	 * @param ch	 * @return	 */	public static boolean isUpperLetter(char ch) {		return ch >= 0x41 && ch <= 0x5A;	}	/**	 * 是否是大写字母字符串([A-Z])	 * 	 * @param ch	 * @return	 */	public static boolean isUpperLetter(String input) {		return isMatches(TYPE_UPPER_LETTER,input);	}	/**	 * 是否包含大写字母字符串([A-Z])	 * 	 * @param input	 * @return	 */	public static boolean isIncludeUpperLetter(String input) {		return isMatchesInclude(TYPE_UPPER_LETTER,input);	}	/**	 * 是否是字母字符串([A-Za-z])	 * 	 * @param ch	 * @return	 */	public static boolean isLetter(char ch) {		return isLowerLetter(ch) || isUpperLetter(ch);	}	/**	 * 是否是汉字字符(广义上的汉字字符,很多都无法用输入法输出的汉字)	 * 	 * @param c	 * @return	 */	public static boolean isCJK(char c) {		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS // CJK统一汉字 \u4E00-\u9fAF				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A // CJK统一汉字扩展-A \u3400-\u4dBF				|| ub == Character.UnicodeBlock.CJK_COMPATIBIliTY_IDEOGRAPHS // CJK兼容汉字 \uF900-\uFAFF				|| ub == Character.UnicodeBlock.CJK_SYMBolS_AND_PUNCTUATION // CJK符号和标点 \u3000-\u303F				|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION // 广义标点 \u2000-\u206F				|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FulLWIDTH_FORMS) { // 半形及全形字符 \uFF00-\uFFEF			return true;		}		return false;	}	/**	 * 是否是汉字字符(不包含标点)	 * 	 * @param c	 * @return	 */	public static boolean isnopunctuationCJK(char c) {		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS // CJK统一汉字 \u4E00-\u9fAF				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A // CJK统一汉字扩展-A \u3400-\u4dBF				|| ub == Character.UnicodeBlock.CJK_COMPATIBIliTY_IDEOGRAPHS) { // CJK兼容汉字 \uF900-\uFAFF			return true;		}		return false;	}	/**	 * 是否是汉字字符(不包含标点)	 * 	 * @param c	 * @return	 */	public static boolean isnopunctuationCJK(String input) {		return isMatches(TYPE_NO_PUNCTUATION_CJK,input);	}	/**	 * 是否是汉字字符串(广义上的汉字字符,很多都无法用输入法输出的汉字)	 * 	 * @param input	 * @return	 */	public static boolean isCJK(String input) {		return isMatches(TYPE_CJK,input);	}	/**	 * 是否包含汉字字符串(广义上的汉字字符,很多都无法用输入法输出的汉字)	 * 	 * @param input	 * @return	 */	public static boolean isIncludeCJK(String input) {		return isMatchesInclude(TYPE_CJK,input);	}	/**	 * 是否是空白字符	 * 	 * @param input	 * @return	 */	public static boolean isWhitespace(String input) {		return isMatches(TYPE_WHITESPACE,input);	}	/**	 * 是否包含空白字符	 * 	 * @param input	 * @return	 */	public static boolean isIncludeWhitespace(String input) {		return isMatchesInclude(TYPE_WHITESPACE,input);	}}

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



	/**	 * 此接口定义了排序规则中最基本的字段,子类用哪些字段排序由子类自己决定, 以下是目前的规则(优先级高的放在前面) 1.群组排序字段:状态、群组名称 2.讨论组排序字段:论组名称 3.好友排序字段:备注、昵称、电话号码、飞信号(此好友只联系人列表好友、讨论组成员列表、群组成员列表)	 */	public interface BaseSortColumns extends BaseColumns {		/** 是否全是数字或者特殊字符或者生僻字 0 正常 1 不正常 */		public static final String SPECIAL_CHaraCTERS = "special_characters";		/** 英文、中文、中英文规则;全部英文为1,中英混合为2 ,全部中文为100 */		public static final String ENGliSH_CHInesE_ORDER = "english_chinese_order";		/** 好友排序key */		public static final String SORT_KEY = "sort_key";		/** 此好友是否置顶,1代表是,0代表否 */		public static final String IS_top = "is_top";	}	public class BaseSort implements BaseSortColumns {		/**		 * 不全是数字和字符		 * */		public static final int TYPE_name_norMAL = 0;		/**		 * 全是数字或特殊字符		 * */		public static final int TYPE_name_UNnorMAL = 1;		/**		 * 全是英文		 * */		public static final int TYPE_ENGliSH_ALL = 2;		/**		 * 全是汉字		 * */		public static final int TYPE_CHInesE_ALL = 3;		/**		 * 全是数字		 * */		public static final int TYPE_NUMBER_ALL = 4;		/**		 * 全特殊字符		 */		public static final int TYPE_SPECIAL_ALL = 5;	}/**	 * 从sortColumns中选择用来排序的字段,sortColumns要中排在前面的优先级高	 * 	 * @param contentValues	 * @param sortColumns	 */	public static voID SetBaseSortKey(ContentValues contentValues,String[] sortColumns) {		if (null == sortColumns || sortColumns.length <= 0 || null == contentValues || contentValues.size() <= 0) {			return;		}		String sortKey = null;		for (int i = 0; i < sortColumns.length; i++) {			sortKey = contentValues.getAsstring(sortColumns[i]);			if (!TextUtils.isEmpty(sortKey) && sortKey.trim().length() > 0) {				break;			}		}		StringBuilder builder = new StringBuilder();		for (int i = 0; i < sortColumns.length; i++) {			builder.append("sort column:").append(sortColumns[i]).append("  column value:").append(contentValues.getAsstring(sortColumns[i]));		}		LogF.d(reset_TAG,"---resetContactValues,sortKey = " + builder.toString());		parseAndInsertBaseSortKey(contentValues,sortKey);	}	/**	 * 解析sortkey,保存到BaseSortColumn.sortKey中	 * 	 * @param contentValues	 * @param sortColumns	 */	private static voID parseAndInsertBaseSortKey(ContentValues contentValues,String sortKey) {		if (!TextUtils.isEmpty(sortKey)) {			String pinyins = null;			char firstChar = sortKey.charat(0);			if (MatcherUtil.isLetter(firstChar)) {				contentValues.put(BaseSortColumns.SPECIAL_CHaraCTERS,BaseSort.TYPE_name_norMAL);				contentValues.put(BaseSortColumns.ENGliSH_CHInesE_ORDER,BaseSort.TYPE_ENGliSH_ALL);				if (MatcherUtil.isIncludeCJK(sortKey)) {					pinyins = PinyinHelper.getInstance().getPinyins(sortKey," ");				}				LogF.d(TAG,"resetContactValues.sortKey = " + sortKey + ",firstChar is letter" + (pinyins == null ? "" : ",pinyins = " + pinyins));			} else if (MatcherUtil.isDigit(String.valueOf(firstChar))) {				contentValues.put(BaseSortColumns.SPECIAL_CHaraCTERS,BaseSort.TYPE_name_UNnorMAL);				contentValues.put(BaseSortColumns.ENGliSH_CHInesE_ORDER,BaseSort.TYPE_NUMBER_ALL);				if (MatcherUtil.isIncludeCJK(sortKey)) {					pinyins = PinyinHelper.getInstance().getPinyins(sortKey,firstChar is digit" + (pinyins == null ? "" : ",pinyins = " + pinyins));			} else if (MatcherUtil.isnopunctuationCJK(firstChar)) {				contentValues.put(BaseSortColumns.SPECIAL_CHaraCTERS,BaseSort.TYPE_CHInesE_ALL);				pinyins = PinyinHelper.getInstance().getPinyins(sortKey," ");				LogF.d(TAG,firstChar is cjk,pinyins = " + pinyins);			} else {				if (MatcherUtil.isIncludeCJK(sortKey)) {					pinyins = PinyinHelper.getInstance().getPinyins(sortKey," ");				}				contentValues.put(BaseSortColumns.SPECIAL_CHaraCTERS,BaseSort.TYPE_SPECIAL_ALL);			}			sortKey=TextUtils.isEmpty(pinyins) ? sortKey : pinyins;			StringBuffer sb=new StringBuffer();			char tmpChar=1;			for(int index=0;index<sortKey.length();index++){				tmpChar=sortKey.charat(index);				if(Character.isDigit(tmpChar)){					tmpChar = (char) (tmpChar - ASCII_ZERO + ASCII_CUSTOM_NUMBER_FirsT);				}				sb.append(tmpChar);			}			contentValues.put(BaseSortColumns.soRT_KEY,sb.toString());		}	}
总结

以上是内存溢出为你收集整理的sqlite字母数字混合排序问题全部内容,希望文章能够帮你解决sqlite字母数字混合排序问题所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1172583.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存