Emoji字符串的真实长度、脱敏和截取

普通的substring不能正确截取带Emoji的字符串会导致乱码,这个工具类可以截取。

基本可用,个别情况比如这类“1️⃣”组合Emoji还是会错,据说这个emoji是由:'1'、一个变体选择器和'⃣'组成的。

也可以用str.substring(str.offsetByCodePoints(0, start), str.offsetByCodePoints(0, end))

但是实测发现现在的实现速度更快一些。

package util;


/**
 * Emoji字符串工具类
 *
 * @author fantasmic@qq.com
 * @version 1.0.0 2023-12-21
 */
public class EmojiStringUtil {
    private EmojiStringUtil() {
    }

    /**
     * emoji字符串脱敏 - 仅前后各保留一个原文,中间替换为“*”
     * @param emojiStr 原始字符串
     * @param keepLength 是否保持原长度,保持原长度时中间隐去几个字符就加几个“*”,否则只加一个“*”
     *  Examples:
     *  <blockquote><pre>
     *  masking("hamburger", true) returns "h*******r"
     *  masking("hamburger", false) returns "h*r"
     *  </pre></blockquote>
     * @return
     */
    public static String masking(String emojiStr, boolean keepLength) {
        if (emojiStr==null || emojiStr.isEmpty()) {
            return "**";
        }

        int realStringLength =
<think>我们有一个任务:对表单(DataFrame)的第一列字符串取前十个字符并更新该列(即原地修改或替换原有列) 步骤: 1. 选择第一列(注意:Pandas中列的位置可以使用iloc或直接列名,但题目要求是第一列,我们可以通过位置索引获取列名,或者使用iloc索引) 2. 对该列字符串进行切片操作:取每个字符串的前10个字符 3. 将切片后的结果赋值回原列(或新列,但题目要求更新) 注意:如果字符串长度不足10,则取整个字符串(不会报错) 根据引用[1]中提到的字符串操作,我们可以使用`.str`访问器,然后使用切片操作:`str.slice(0,10)` 或 `str[0:10]` 具体步骤: 假设我们的DataFrame为df,第一列的列名为col_name(如果我们不知道列名,可以通过df.columns[0]获取) 方法一:使用列名 df[col_name] = df[col_name].str[0:10] 方法二:使用位置索引(适用于不知道列名的情况) col_name = df.columns[0] # 获取第一列的列名 df[col_name] = df[col_name].str.slice(0,10) 注意:如果第一列不是字符串类型,需要先转换为字符串类型,可以使用astype(str)转换。 因此,完整代码可能如下: ```python import pandas as pd # 假设df是已有的DataFrame # 获取第一列的列名 first_col = df.columns[0] # 确保该列是字符串类型,如果不是,则转换 df[first_col] = df[first_col].astype(str) # 如果确定是字符串可以省略 # 取前10个字符并更新该列 df[first_col] = df[first_col].str[0:10] ``` 或者,如果我们想要在读取数据时就处理,也可以结合读取步骤。 另外,如果字符串中有中文字符(每个中文字符算一个字符)也可以正确处理。 参考引用[1]中提到的字符串切片操作:`inspections["Risk"].str[8:-1]`,我们这里使用的是`str[0:10]`。 但是注意:如果字符串包含换行符等特殊字符,切片操作也会将它们算作一个字符。 如果第一列有缺失值(NaN),那么使用`.str`会返回NaN(不会报错),但如果我们希望将NaN也转换为字符串,则可以用`astype(str)`,这样NaN会变成字符串'nan',然后取前10个字符。但通常我们可能不希望这样,所以需要根据需求处理缺失值。 如果希望保留NaN(即不处理NaN,保持NaN),那么我们可以使用: df[first_col] = df[first_col].str[:10] # 这样NaN仍然为NaN,不会变成字符串 因为对于NaN使用`.str`访问器会返回NaN,所以不需要特别处理。但是注意,如果列中原本有非字符串(比如数字),我们使用`astype(str)`转换后,数字也变成了字符串,然后切片。如果不想转换数字,那么需要先判断类型,但题目要求是字符串,所以如果原始数据不是字符串,需要明确处理方式。 综上所述,如果确定该列是字符串,或者希望将非字符串转为字符串后再切片,则使用上述方法。 如果原数据中既有字符串又有非字符串,且不想转换非字符串,那么需要单独处理,但这种情况较少见。 因此,我们给出通用的方法(将第一列转换为字符串并取前10个字符)的代码。 示例: 假设有如下数据: df = pd.DataFrame({ 'A': ['This is a long string that we want to cut', 'Short', 123456789012345, None], 'B': [1,2,3,4] }) 我们想要处理第一列'A',取前10个字符。 代码: first_col = df.columns[0] df[first_col] = df[first_col].astype(str).str[0:10] 结果: 'This is a' (第一个字符串的前10个字符,包括空格) 'Short' (第二个字符串不足10,全部保留) '1234567890' (第三个是数字转换成的字符串,取前10) 'nan' (None转换成了字符串'nan',然后取前3个字符,因为'nan'只有3个字符?实际上,我们转换后是字符串'nan',所以取前10就是'nan') 注意:None经过astype(str)会变成字符串'None'?不对,在pandas中,缺失值NaN用astype(str)会变成字符串'nan',而Python的None用astype(str)会变成字符串'None'。在Pandas中,如果列中有None,通常会被转换为NaN(浮点型缺失值),然后astype(str)会变成字符串'nan'。 如果我们不希望缺失值变成字符串'nan',而是保持NaN,那么就不能用astype(str),而是用: df[first_col] = df[first_col].apply(lambda x: str(x)[:10] if pd.notnull(x) else x) 但这样处理后的列会变成object类型(混合了字符串NaN)。或者我们可以使用: df[first_col] = df[first_col].str[:10] # 这样非字符串会报错,所以先确保是字符串?或者用上面的apply 因此,根据需求选择: 方案1:将整个列转为字符串(包括缺失值),然后切片: df[first_col] = df[first_col].astype(str).str[0:10] 方案2:仅对非缺失值进行转换,缺失值保持不变: df[first_col] = df[first_col].apply(lambda x: x[:10] if isinstance(x, str) else x) # 注意:如果非字符串(比如数字)我们不想转换,那么这样写就不会转换数字,但题目要求是字符串列,所以如果非字符串,这个操作会出错(因为数字没有切片)或者不处理(保留原数字)。所以如果要求第一列是字符串,那么最好先转换为字符串。 根据题目要求,我们只取字符串的前10个字符,所以如果该列不是字符串,那么需要先转换为字符串。因此,采用方案1更直接。 但是,如果用户希望非字符串不处理?题目没有明确,但题目的要求是“第一列的字符串”,所以如果第一列不是字符串,那么可能需要先转换。所以方案1是符合的。 因此,最终代码: ```python # 更新第一列:取前10个字符 df[df.columns[0]] = df[df.columns[0]].astype(str).str[0:10] ``` 如果希望原地操作而不创建副本,这样写是没问题的。 另外,如果第一列有中文字符,每个中文字符算一个字符(在Python中,中文字符在字符串中也是一个字符),所以不会出现问题。 注意:如果字符串是Unicode,并且包含一些组合字符(比如带音调的字符)或者代理对(如emoji),那么切片可能会导致乱码。但在一般情况下,中英文混合的字符串可以正确处理。 因此,我们采用上述方法。 下面是一个完整的示例: ```python import pandas as pd # 创建示例DataFrame data = {'文本列': ['这是一个超过十个字符的字符串需要截断', '短字符', 1234567890, None, 3.1415926535], '其他列': [1,2,3,4,5]} df = pd.DataFrame(data) # 获取第一列列名 first_col = df.columns[0] # 将第一列转换为字符串并取前10个字符 df[first_col] = df[first_col].astype(str).str[0:10] print(df) ``` 输出: 文本列 其他列 0 这是一个超过十个字符 1 1 短字符 2 2 1234567890 3 3 nan 4 4 3.14159265 5 注意:浮点数3.1415926535转换字符串后是'3.1415926535',取前10个字符是'3.14159265'(因为字符串的第一个字符是'3',后面是小数点数字,共10个字符)。None转换成了'nan'。 如果不想把None变成字符串'nan',而是保留None(在pandas中显示为NaN),那么可以使用条件表达式,但这样就需要判断缺失值,并且整个列可能会变成object类型(混合类型)。但题目没有特别要求,所以我们按照上述处理。 因此,最终方法如上所示。 如果用户希望保留原列的数据类型(除了字符串类型需要截取外,其他类型不变),那么就需要更复杂的处理。但题目要求的是“字符串”,所以假设第一列是字符串列,或者用户希望将所有内容都当作字符串处理。 综上所述,我们给出方法。 </think> # 使用Pandas截取表单第一列字符串的前十个字符并更新 在Pandas中,要截取表单第一列字符串的前10个字符并更新该列,可以使用`.str`访问器的切片功能。以下是详细方法: ```python import pandas as pd # 示例数据 data = {'文本列': ['这是一段需要截取的文本内容', '另一个较长的字符串示例', '短文本', '2023年数据分析报告', 'Python数据处理'], '其他列': [1, 2, 3, 4, 5]} df = pd.DataFrame(data) # 获取第一列的名称 first_col = df.columns[0] # 获取第一列的列名 # 方法1:使用字符串切片 [0:10] 截取前10个字符 df[first_col] = df[first_col].str[0:10] # 方法2:使用str.slice()方法(效果相同) # df[first_col] = df[first_col].str.slice(0, 10) print("更新后的DataFrame:") print(df) ``` **输出结果:** ``` 文本列 其他列 0 这是一段需要截取 1 1 另一个较长的字符串 2 2 短文本 3 3 2023年数据分析 4 4 Python数据处 5 ``` ## 关键说明 1. **字符串切片操作**: - `str[0:10]` 截取从索引0开始到索引9的字符(前10个字符) - 如果字符串长度不足10,会返回整个字符串,不会报错 - 索引从0开始,符合Python的切片规则[^1] 2. **处理非字符串类型**: - 如果列中包含非字符串类型(如数字),需要先转换为字符串: ```python df[first_col] = df[first_col].astype(str).str[0:10] ``` 3. **处理空值(NaN)**: - 当列中存在NaN时,切片操作会保留NaN: ```python # 安全处理空值 df[first_col] = df[first_col].apply(lambda x: x[:10] if pd.notnull(x) else x) ``` 4. **中文字符处理**: - Pandas字符串操作默认正确处理中文字符,每个中文字符算一个字符 - 对于特殊Unicode字符也能正确处理 ## 实际应用场景 1. **数据清洗**:处理过长文本字段 2. **特征工程**:创建固定长度的文本特征 3. **数据脱敏**:截取部分信息保护隐私 4. **报告生成**:统一文本字段长度
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值