Delphi 2009 新增单元 Character[2]: IsLetter、IsUpper、IsLower、IsDigit、IsNumber

本博客针对Delphi编程中如何判断字符串是否包含全角字符或特定字符进行了详细解答,包括使用`isnumber`函数时遇到的问题及解决办法。

======================================================
注:本文源代码点此下载
======================================================

#1楼 2008-08-28 13:26 开心王男[未注册用户]

str := 'ab32汉字';

if(not isletter(str[i])) and (not isdigit(str[i])) and (not isnumber(str[i])) then

what?

呵呵,万老师有没有最简洁的办法判断是不是全角字符的一半,或者说是不是汉字的一半,谢谢回复

回复 引用

#2楼 2008-08-28 13:27 开心王男[未注册用户]

上面的i=5

回复 引用

#3楼[楼主] 2008-08-28 13:34 万一

@开心王男

character 中应该有; 我还没测试到.

回复 引用 查看

#4楼 2009-03-12 17:38 zhouying82[未注册用户]

我用

if (isnumber(str(edit1.text))) then

......

怎么会出错?

回复 引用

#5楼[楼主] 2009-03-12 18:31 万一

@zhouying82

嘿, 你肯定是刚转到 delphi 上来.

回复 引用 查看

#6楼 2009-03-12 22:32 zhouying82[未注册用户]

万老师告诉我答案啊?

回复 引用

#7楼[楼主] 2009-03-12 22:59 万一

@zhouying82

isnumber 的参数应该是一个字符;

字符串转换到整数可用 strtoint 或 strtointdef.

回复 引用 查看

#8楼 2009-03-12 23:05 zhouying82[未注册用户]

我知道,但是我看说明好像isnumber后面要跟字符啊,str函数就是字符串转为字符的函数啊?

回复 引用

#9楼[楼主] 2009-03-12 23:14 万一

@zhouying82

str 是将数字格式化为字符串:

http://www.cnblogs.com/del/archive/2008/03/29/1129279.html

直接告诉我你的目的好吗?

回复 引用 查看

#10楼 2009-03-12 23:32 zhouying82[未注册用户]

哦,理解了。谢谢

回复 引用

注册用户登录后才能发表评论,请 登录 或 注册,返回博客园首页

首页博问闪存新闻园子招聘知识库

最新it新闻:

·ios 5.1 beta3文件预示未来 siri有可能支持 ipad和 ipod touch

·android平台12月广告浏览份额51.6% 超越ios

·测试版ios源代码显示ipad 3或将支持siri

·斯蒂芬·霍金的新电脑

·京东商城2.95亿竞得北京商业地一块

» 更多新闻...

最新知识库文章:

·javascript 面向对象编程

·持续集成之“everything is code”

·持续集成之“软件自我识别”

·持续集成之戏说check-in dance

·什么是闭包。
       我的理解

» 更多知识库文章...

china-pub 2011秋季教材巡展

china-pub 计算机绝版图书按需印刷服务

copyright ©2012 万一 powered by: 博客园 模板提供:沪江博客


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
<think>我们正在处理用户的问题:理解Java中使用Stream API进行数据清洗(过滤非字母字符)的原理和实现方式。 用户特别提到了flatMap, mapToObj, Character::isLetter等。 根据用户的问题,我们需要解释如何使用Stream API来过滤掉字符串中的非字母字符,只保留字母字符。 通常,我们可以将字符串转换为字符流,然后过滤掉非字母字符,最后将过滤后的字符重新组合成字符串。 参考引用[3]中提到了Stream API的map操作,但这里我们可能需要用到filter和flatMap等操作。 步骤: 1. 将字符串转换为字符流:可以使用String的chars()方法得到一个IntStream(字符的int值流),或者使用codePoints()处理Unicode字符。 2. 将int值转换为字符:可以使用mapToObj将其转换为Character对象,或者直接处理char。 3. 过滤非字母字符:使用filter(Character::isLetter)来保留字母字符。 4. 将过滤后的字符重新组合成字符串:可以使用Collectors.joining()。 另外,用户提到了flatMap,这通常用于将每个元素映射为一个流,然后将这些流扁平化。在过滤非字母字符的场景中,如果我们有多个字符串(比如一个字符串列表),我们可以使用flatMap来将每个字符串拆分成字符流,然后统一处理。 下面我们分别给出两种场景的示例: 场景1:单个字符串的字母清洗 场景2:字符串列表的字母清洗(使用flatMap) 注意:Character.isLetter方法可以判断一个字符是否是字母(包括各种语言的字母)。 实现示例: 场景1:单个字符串 例如,将字符串"Hello, World! 123"清洗为"HelloWorld" 代码: ```java String input = "Hello, World! 123"; String cleaned = input.chars() // 生成IntStream .mapToObj(c -> (char)c) // 将int转换为Character .filter(Character::isLetter) // 过滤非字母 .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) .toString(); ``` 或者更简洁地使用: ```java String cleaned = input.chars() .filter(Character::isLetter) // 这里可以直接使用int值,因为Character.isLetter有接受int的重载方法 .collect(StringBuilder::new, (sb, c) -> sb.append((char)c), StringBuilder::append) .toString(); ``` 但是注意:Character.isLetter(int)方法可以接受int参数(表示字符的Unicode码点),所以我们可以避免转换为char对象,直接过滤: 改进版: ```java String cleaned = input.chars() .filter(Character::isLetter) // 使用Character.isLetter(int)方法 .collect(StringBuilder::new, (sb, codePoint) -> sb.append((char) codePoint), StringBuilder::append) .toString(); ``` 或者使用mapToObj和joining(更简单): ```java String cleaned = input.chars() .filter(Character::isLetter) .mapToObj(c -> String.valueOf((char) c)) .collect(Collectors.joining()); ``` 场景2:字符串列表的清洗(使用flatMap) 例如,有一个字符串列表,我们想将每个字符串清洗后,再合并成一个字符串(或者分别清洗每个字符串)。 如果我们要将整个列表的字符都合并成一个字符串并清洗: ```java List<String> list = Arrays.asList("Hello,", "World! 123"); String cleanedAll = list.stream() // 流元素是字符串 .flatMap(str -> str.chars().boxed()) // 将每个字符串转换为IntStream,然后boxed成Stream<Integer>,但这样并不好,因为后面还要转换 .filter(Character::isLetter) // 这里使用int值,但boxed后是Integer,需要拆箱 .map(c -> (char) c.intValue()) // 转换为字符 .map(String::valueOf) // 转换为字符串 .collect(Collectors.joining()); ``` 更优的方法是避免boxed,直接使用flatMapToInt: ```java String cleanedAll = list.stream() .flatMapToInt(str -> str.chars()) // 生成一个IntStream .filter(Character::isLetter) .collect(StringBuilder::new, (sb, c) -> sb.append((char)c), StringBuilder::append) .toString(); ``` 或者,如果我们想分别清洗每个字符串,则不需要flatMap,而是对每个字符串进行清洗操作: ```java List<String> cleanedList = list.stream() .map(str -> str.chars() .filter(Character::isLetter) .collect(StringBuilder::new, (sb, c) -> sb.append((char)c), StringBuilder::append) .toString() ) .collect(Collectors.toList()); ``` 原理: - Stream API提供了一种声明式处理数据的方式,通过链式操作(生成流、中间操作、终止操作)来转换数据。 - 数据清洗通常包括:转换(如拆分字符串)、过滤(去除不需要的元素)、收集(重新组合)。 - 使用flatMap可以将多个流合并成一个流,便于统一处理。 注意:在处理字符时,我们需要注意字符编码(如UTF-8)和Unicode字符(比如使用codePoints()方法处理增补字符),但在这个问题中,我们假设输入是基本多语言平面(BMP)的字符,所以使用chars()足够。如果涉及增补字符(如emoji),则应该使用codePoints()。 根据引用[1]和[2]中提到的字符编码,我们在处理流时,实际上已经将字符串视为Unicode字符序列(在Java中内部使用UTF-16)。但chars()方法返回的是UTF-16代码单元(char值的int表示),对于增补字符,一个字符由两个char组成(代理对)。而Character.isLetter(int)方法可以处理完整的Unicode码点(包括增补字符)。但注意,chars()方法返回的是代码单元,不是码点。因此,如果输入可能包含增补字符,我们应该使用codePoints()方法。 例如,对于包含增补字符的字符串: ```java String input = "A😀B"; String cleaned = input.codePoints() // 返回IntStream,每个元素是一个码点 .filter(Character::isLetter) // 判断整个码点是否是字母 .collect(StringBuilder::new, (sb, codePoint) -> sb.appendCodePoint(codePoint), StringBuilder::append) .toString(); ``` 这样,增补字符(如😀)会被当作一个整体处理。 总结: 根据需求选择chars()或codePoints(),然后使用filter(Character::isLetter)过滤,最后收集为字符串。 现在,我们可以按照上述思路给用户一个清晰的回答。</think>### Java Stream API 字符过滤与字母清洗解析 #### 核心原理 Java Stream API 进行字符清洗的核心流程为: 1. **字符拆分**:将字符串拆分为单个字符流 2. **字符过滤**:使用谓词(如`Character::isLetter`)过滤非字母字符 3. **结果重组**:将过滤后的字符重新组合为字符串 其中`Character::isLetter`方法可识别所有Unicode字母字符(包括中文、英文等),其底层实现基于Unicode标准分类[^1]。 #### 实现方式对比 ##### 1. 基础实现(`filter` + `collect`) ```java String input = "H3ll0, 世界!"; String cleaned = input.chars() // 生成IntStream .mapToObj(c -> (char)c) // 转为Character流 .filter(Character::isLetter) // 过滤非字母字符 .collect(StringBuilder::new, // 重组字符串 StringBuilder::append, StringBuilder::append) .toString(); // 结果: "Hello世界" ``` ##### 2. 优化实现(`filter` + `mapToObj`) ```java String cleaned = input.chars() .filter(Character::isLetter) // 直接过滤int值 .mapToObj(c -> String.valueOf((char)c)) .collect(Collectors.joining()); ``` ##### 3. 多字符串处理(`flatMap`) ```java List<String> texts = Arrays.asList("A1B", "C_2D"); String combined = texts.stream() .flatMap(s -> s.chars().boxed()) // 扁平化为字符流 .filter(Character::isLetter) .map(c -> String.valueOf((char)c.intValue())) .collect(Collectors.joining()); // 结果: "ABCD" ``` #### 关键技术解析 1. **`chars()`方法** 将字符串转换为`IntStream`,每个int值对应字符的Unicode码点 2. **`Character::isLetter`** 等效于`codePoint -> Character.isLetter((char)codePoint)`,识别所有字母字符 3. **`flatMap` vs `map`** - `map`:1:1元素转换 - `flatMap`:1:N元素转换(将流元素展开为子流) 4. **类型转换** `mapToObj(c -> (char)c)`将int流转换为Character对象流,避免直接操作原始类型 #### 编码注意事项 1. 处理多语言文本时,优先使用`codePoints()`替代`chars()`以支持增补字符 ```java String cleaned = input.codePoints() .filter(Character::isLetter) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString(); ``` 2. 需要保留字符位置信息时,可结合`IntStream.range()`: ```java IntStream.range(0, input.length()) .filter(i -> Character.isLetter(input.charAt(i))) .mapToObj(i -> String.valueOf(input.charAt(i))) .collect(Collectors.joining()); ``` #### 性能建议 1. 单字符串处理:直接使用`StringBuilder`收集 2. 大数据量:使用并行流`parallel()` + 线程安全收集器 3. 复用谓词:预先编译`Predicate<Character> isLetter = Character::isLetter`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值