今天在搜索判断字符是否是中文的时候看到一道面试题目:
题目 写道
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+汉的半个”。
我写了一个较共用的,可以截取一个字符串中的任意一段,支持编码:
public static boolean isChinseseChar(char ch) {
Pattern p = Pattern.compile("[\\u4e00-\\u9fa5]");
return p.matcher(ch+"").find();
}
/**
* 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。
* 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+汉的半个”。
* @param source 源字符串
* @param startPos 开始字节数
* @param endPos 结束字节数
* @param charset 编码类型
* @return 截取的字符串
* @throws UnsupportedEncodingException
*/
public static String cutString(String source,int startPos, int endPos, String charset) throws UnsupportedEncodingException{
byte[] bs = source.getBytes(charset);
if(startPos > bs.length)
throw new RuntimeException("startPos大于字符" + source + "的总共字节数!");
if(endPos > bs.length)
endPos = bs.length;
int offset = 0;
int factor = "编".getBytes(charset).length;
int start = -1, end = -1;
for(int i=0; i<source.length(); i++) {
if(offset == startPos)//offset = startPos,其实位置的字节数正好是一个非中文字开头
start = i;
if(offset > startPos && start == -1)//offset已经大于startPos但是还没找到offset=startPos的位置,说明开始的是一个中文字符
start = i;
if(isChinseseChar(source.charAt(i)))
offset += factor;
else
offset ++;
if(offset == endPos){
end = i+1;
}
if(offset > endPos && end == -1) {
end = i;
}
if(start != -1 && end != -1)
break;
}
if(start >= end)
return "";
return source.substring(start,end);
}
public static String cutString(String source,int startPos,int endPos) throws UnsupportedEncodingException{
return cutString(source,startPos,endPos,Charset.defaultCharset().toString());
}
public static String cutString(String source,int endPos) throws UnsupportedEncodingException{
return cutString(source,0,endPos,Charset.defaultCharset().toString());
}
public static String cutString(String source,int endPos, String charset) throws UnsupportedEncodingException{
return cutString(source,0,endPos,charset);
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String source = "我是abc";
System.out.println(source+"[0,4](gbk): "+cutString(source,0,4,"gbk"));
System.out.println(source+"[0,4](utf-8): "+cutString(source,0,4,"utf-8"));
source = "adf12我是abc";
System.out.println(source+"[0,2](gbk): "+cutString(source,0,2,"gbk"));
System.out.println(source+"[0,2](utf-8): "+cutString(source,0,2,"utf-8"));
source = "add她fdf2我是abc";
System.out.println(source+"[0,11](gbk): "+cutString(source,0,11,"gbk"));
System.out.println(source+"[0,11](utf-8): "+cutString(source,0,11,"utf-8"));
System.out.println(source+"[10,11](gbk): "+cutString(source,10,11,"gbk"));
System.out.println(source+"[10,11](utf-8): "+cutString(source,10,11,"utf-8"));
System.out.println(source+"[8,12](gbk): "+cutString(source,8,12,"gbk"));
System.out.println(source+"[8,12](utf-8): "+cutString(source,8,12,"utf-8"));
System.out.println(source+"[9,11](gbk): "+cutString(source,9,11,"gbk"));
System.out.println(source+"[9,11](utf-8): "+cutString(source,9,11,"utf-8"));
System.out.println(source+"[0,20](gbk): "+cutString(source,0,20,"gbk"));
System.out.println(source+"[0,20](utf-8): "+cutString(source,0,20,"utf-8"));
}
打印结果:
写道
我是abc[0,4](gbk): 我是
我是abc[0,4](utf-8): 我
adf12我是abc[0,2](gbk): ad
adf12我是abc[0,2](utf-8): ad
add她fdf2我是abc[0,11](gbk): add她fdf2我
add她fdf2我是abc[0,11](utf-8): add她fdf2
add她fdf2我是abc[10,11](gbk):
add她fdf2我是abc[10,11](utf-8):
add她fdf2我是abc[8,12](gbk): 2我
add她fdf2我是abc[8,12](utf-8): f2
add她fdf2我是abc[9,11](gbk): 我
add她fdf2我是abc[9,11](utf-8): 2
add她fdf2我是abc[0,20](gbk): add她fdf2我是abc
add她fdf2我是abc[0,20](utf-8): add她fdf2我是abc
分享到:
相关推荐
SQL截取字符串函数(1、截取从字符串左边开始N个字符 2、截取从字符串右边开始N个字符(例如取字符www.163.com) 3、截取字符串中任意位置及长度 等等)
string常用截取字符串方法有很多,但是配合使用以下两种,基本都能满足要求: find(string strSub, npos); find_last_of(string strSub, npos); 其中strSub是需要寻找的子字符串,npos为查找起始位置。找到返回子...
oracle,按特定字符,截取字符串,直接出结果 oracle,按特定字符,截取字符串,直接出结果oracle,按特定字符,截取字符串,直接出结果
C# 按照字节长度截取字符串,可以截取任意字节长度得字符串,使用了一点正则表达式。
bat截取字符串
用SQL语句截取字符串, string substr ( string string, int start [, int length]) 参数1:处理字符串 参数2:截取的起始位置(第一个字符是从0开始) 参数3:截取的字符数量
js截取字符串常用的方法很多,你知道多少呢?看看String和StringBuffer如何截取字符串的
这个小demo是截取字符串的,有2个代码,还有取消字符串中的空格,可以看看。
适合刚刚进入(JavaScript,Vue)编程领域的小白使用
substring截取字符串 substring截取字符串 substring截取字符串 substring截取字符串 substring截取字符串 substring截取字符串 substring截取字符串 substring截取字符串 substring截取字符串 substring截取字符串 ...
ASP截取字符串(既:利用asp代码控制字符的显示)
CString截取字符串全攻略 - fox的日志 - 网易博客.mht
C#经常用到的几个截取字符串1 取字符串的前i个字符2 去掉字符串的前i个字符:3 从右边开始取i个字符:
vb asp中根据符号截取字符串方法 split (",")
asp.net截取字符串方法 使用字节精确计算 计算空格 直接复制使用 简单
js截取字符串函数.txt
delphi 实现截取字符串中中文+英文混合截取,当字符串中包含中文和英文支付时,有时候会将一个中文截取1半,出现乱码。该demo能很好的解决该问题
自己输入一个字符串,字符串中可以包括字符和汉字,截取指定的字符串
给写了2个方法,一个是直接截取单个需要的字符串,比如字符串string a="ab123456",我只需要提取3,那么就是单独截取就可以了,从2开始到4结束就行。 第二个是把所有的符合条件的字符串都截取出来,提取出来,比如...
Java精确截取字符串