java移除/去掉字符串指定前缀以及清除字符串下划线的方法

本文介绍了一种去除字符串指定前缀的方法,并提供了一个示例代码实现。此外,还详细描述了如何通过分割和拼接操作清除字符串中的下划线,形成驼峰式命名风格。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

去掉字符串指定的前缀

  1. 利用正则判断字符串前缀是否存在str.toLowerCase().matches("^" + pf.toLowerCase() + “.*”)
  2. 如果存在,利用substring截取前缀字符串长度的后面的字符串
  3. 方法如下:
    /**
     * 去掉字符串指定的前缀
     * @param str 字符串名称
     * @param prefix 前缀数组
     * @return
     */
    public static String removePrefix(String str, String[] prefix) {
        if (StringUtils.isEmpty(str)) {
            return "";
        } else {
            if (null != prefix) {
                String[] prefixArray = prefix;

                for(int i = 0; i < prefix.length; ++i) {
                    String pf = prefixArray[i];
                    if (str.toLowerCase().matches("^" + pf.toLowerCase() + ".*")) {
                        return str.substring(pf.length());//截取前缀后面的字符串
                    }
                }
            }

            return str;
        }
    }
   public static void main(String[] args) {
        String[] prefix = {"pre_","log_"};//去掉字符串前缀为pre_、log_
        String str = "pre_name";//测试字符串
        System.out.println(removePrefix(str,prefix));
    }

在这里插入图片描述

清除字符串下划线

  1. 利用split分割成字符串数组
  2. 遍历数组,用StringBuffer拼接字符串,下划线后的首字母大写(驼峰结构)
  3. 方法如下:
    /**
     * 清除字符串下划线
     * @param strKey
     * @return
     */
    public static String getNoUnderlineStr(String strKey){
        if(strKey.indexOf("_")!=-1){
            String[] keyArray = strKey.split("_");
            StringBuffer sb = new StringBuffer();
            boolean flag = false;
            for(String key:keyArray){
                if(flag){
                    //下划线后的首字母大写
                    sb.append(StringUtils.capitalize(key));
                }else{
                    flag=true;
                    sb.append(key);
                }
            }
            strKey = sb.toString();
        }
        return strKey;
    }
<think>我们有一个任务:在Bash脚本中根据子串将10个字符串分类。也就是说,我们有一组字符串(假设10个),我们需要根据它们是否包含特定的子串来将它们分组。 思路: 1. 我们可以定义一组字符串(例如,放在一个数组中)。 2. 定义几个子串(作为分类的关键字)。 3. 遍历数组中的每个字符串,检查它包含哪个关键字(注意:一个字符串可能包含多个关键字?这里我们假设每个字符串只分到一类,或者我们只根据第一个匹配到的关键字分类?或者根据所有匹配到的?但题目要求“分类”,通常一个字符串只能属于一类,所以我们需要明确规则:比如按第一个匹配到的分类,或者按优先级匹配,或者一个字符串只能匹配一个关键字?) 但是,问题没有明确说明一个字符串可能匹配多个关键字的情况。为了简单起见,我们假设: - 每个字符串只根据它包含的第一个关键字(按照关键字的顺序)来分类。如果都不包含,则分到“其他”类。 另一种方式:我们可以为每个关键字建立一个数组,然后遍历字符串,如果字符串包含某个关键字,就把它加入对应的数组,然后停止检查其他关键字(避免一个字符串被分到多个类别)。或者,如果不停止,那么一个字符串可能出现在多个类别中。 根据问题,我们需要“分类”,所以这里我们采用:每个字符串只分到第一个匹配到的关键字对应的类别。如果没有匹配,则分到“其他”。 步骤: 1. 定义关键字数组:keywords=("substr1" "substr2" "substr3") 2. 定义字符串数组:strings=("string1" "string2" ... "string10") 3. 初始化一个关联数组(用于存储分类结果)或者为每个关键字准备一个数组。 4. 遍历每个字符串,然后遍历关键字数组(按顺序),检查当前字符串是否包含当前关键字。如果包含,则将该字符串加入到该关键字的分类数组中,并跳出关键字循环(使用break),继续下一个字符串。如果没有任何关键字匹配,则加入“其他”分类。 注意:在Bash中检查字符串包含关系,我们可以使用通配符模式匹配([[ $string == *"$keyword"* ]])或者使用正则表达式。这里我们使用通配符模式匹配。 5. 最后输出分类结果。 示例: 假设我们有10个字符串strings=( "apple_pie" "banana_bread" "cherry_pie" "blueberry_muffin" "strawberry_shortcake" "chocolate_cake" "vanilla_ice_cream" "carrot_cake" "pumpkin_pie" "cinnamon_roll" ) 我们想根据子串分类:比如包含"pie"的,包含"cake"的,包含"bread"的,其他分到"other"。 关键字数组:keywords=("pie" "cake" "bread") 注意:这里"pie"和"cake"可能同时出现在一个字符串中?比如"piecake"?但我们的例子中没有。所以按照顺序,先匹配到"pie"就不会再匹配"cake"。 实现: 我们将使用Bash数组和循环。 代码结构: ```bash #!/bin/bash # 定义关键字数组(按优先级顺序) keywords=("pie" "cake" "bread") # 定义字符串数组 strings=( "apple_pie" "banana_bread" "cherry_pie" "blueberry_muffin" "strawberry_shortcake" "chocolate_cake" "vanilla_ice_cream" "carrot_cake" "pumpkin_pie" "cinnamon_roll" ) # 初始化分类数组 # 为每个关键字创建一个数组,同时为其他创建一个数组 declare -a pie_array declare -a cake_array declare -a bread_array declare -a other_array # 遍历所有字符串 for str in "${strings[@]}"; do matched=false # 遍历关键字 for kw in "${keywords[@]}"; do if [[ $str == *"$kw"* ]]; then matched=true # 根据关键字将字符串添加到对应的数组 case $kw in "pie") pie_array+=("$str") ;; "cake") cake_array+=("$str") ;; "bread") bread_array+=("$str") ;; esac # 匹配到一个关键字后跳出内层循环,继续下一个字符串 break fi done # 如果没有匹配到任何关键字,则加入其他数组 if [ "$matched" = false ]; then other_array+=("$str") fi done # 输出结果 echo "包含'pie'的字符串:" printf "%s\n" "${pie_array[@]}" echo echo "包含'cake'的字符串:" printf "%s\n" "${cake_array[@]}" echo echo "包含'bread'的字符串:" printf "%s\n" "${bread_array[@]}" echo echo "其他字符串:" printf "%s\n" "${other_array[@]}" ``` 但是,上面的方法在关键字较多时,case语句需要写很多分支。我们可以使用动态的数组名,但这样可能会复杂一些。另一种方法:使用关联数组来存储每个关键字对应的数组,但Bash中数组不能嵌套,所以我们可以用关联数组存储数组的名字?或者使用间接引用。 这里为了简单,我们使用多个数组(如果关键字数量固定且不多)。如果关键字数量很多,我们可以考虑使用一个二维数组(但Bash不支持二维数组)或者使用一个关联数组来存储每个关键字对应的字符串列表(用空格或换行分隔,但注意字符串中不能有特殊字符)。 另一种改进:我们可以使用一个关联数组(分类名称作为键,值是一个字符串,我们不断追加,或者用数组?Bash 4.0以上支持关联数组的值为数组?实际上不支持,所以我们可以用字符串存储,用换行或特定分隔符,或者使用多个数组。 这里我们使用Bash 4.0以上的特性:关联数组,并且为每个分类创建一个数组,但数组名由关键字决定。这需要用到间接引用(eval)或者nameref(Bash 4.3+)。为了避免复杂性,我们使用一个循环来初始化每个关键字对应的数组,然后使用间接变量。 但是,为了代码的清晰和可维护性,我们采用第一种方式(固定关键字)即可。如果关键字是动态的,那么我们需要更复杂的代码。 假设关键字是动态的,我们可以这样: 1. 初始化一个关联数组,用于存储每个关键字对应的数组(但实际上存储的是数组名,然后通过间接引用访问)。 2. 或者,我们可以用一个关联数组,键是关键字,值是一个字符串(包含该类的所有字符串,用换行符或空格分隔)。但这样如果字符串包含空格,就会有问题。 所以,我们使用动态数组名,然后通过nameref(如果支持)或者eval。 由于我们不知道用户使用的Bash版本,这里我们使用更通用的方法:用一个临时文件或避免使用复杂结构。但这样可能不够优雅。 因此,我们折中:使用一个数组来存储所有分类,然后每个分类用一个数组,但关键字数组和分类数组一一对应。然后我们通过索引来访问。 但是,我们也可以将每个分类的数组命名为“array_关键字”,然后使用间接变量。 这里我们使用间接变量(indirect variable): 例如: declare -a array_pie declare -a array_cake ... 然后,在循环中,我们可以根据关键字构造数组名:var_name="array_$kw" 然后使用间接引用:eval 'array=("${'"$var_name"'[@]}")' # 读 或者使用:eval "$var_name"+=('"$str"') # 写 但eval有安全风险,如果关键字是用户输入的,可能包含特殊字符。所以我们需要确保关键字是安全的(只包含字母数字等)。 或者,在Bash 4.3以上,我们可以使用nameref: declare -n ref="array_$kw" ref+=("$str") 但是,我们不知道用户环境,所以这里我们使用第一种固定关键字的方法,并假设关键字是固定的。 为了灵活性,我们假设关键字是动态的,但要求关键字是有效的变量名部分(即只包含字母、数字和下划线)。这样我们可以用关键字作为数组名的一部分。 我们修改代码: 首先,初始化每个关键字对应的数组(空数组): for kw in "${keywords[@]}"; do declare -a "array_$kw" done 然后,在匹配时: if [[ $str == *"$kw"* ]]; then matched=true # 构造数组名 array_name="array_$kw" # 使用间接引用添加元素 eval "$array_name"+=('"$str"') break fi 最后输出时,遍历关键字数组,然后输出每个关键字对应的数组。 但是,eval的使用需要谨慎。我们也可以使用nameref(如果环境支持)。 考虑到兼容性,我们使用第一种简单方法(固定关键字)来演示。如果用户需要动态关键字,可以自行修改。 因此,我们提供两种方案: 方案一:关键字固定(如示例中的三个),使用多个数组(代码如上)。 方案二:关键字动态,使用间接引用(eval)或nameref。 这里我们写一个使用eval的动态版本(注意:如果关键字包含特殊字符,可能出错,所以确保关键字是简单的字符串)。 动态版本: ```bash #!/bin/bash # 定义关键字数组(可以动态增加) keywords=("pie" "cake" "bread") # 定义字符串数组 strings=( "apple_pie" "banana_bread" "cherry_pie" "blueberry_muffin" "strawberry_shortcake" "chocolate_cake" "vanilla_ice_cream" "carrot_cake" "pumpkin_pie" "cinnamon_roll" ) # 初始化一个空数组用于存储没有匹配的字符串 other_array=() # 为每个关键字初始化一个数组 for kw in "${keywords[@]}"; do # 将关键字中的空格替换为下划线(或其他)以确保变量名有效,但这里关键字没有空格,所以直接使用 # 构造数组名 array_name="array_${kw}" # 声明为空数组 eval "declare -a ${array_name}" done # 遍历所有字符串 for str in "${strings[@]}"; do matched=false # 遍历关键字 for kw in "${keywords[@]}"; do if [[ $str == *"$kw"* ]]; then matched=true array_name="array_${kw}" # 使用间接引用将字符串添加到数组 eval "${array_name}"+=('"$str"') break fi done # 如果没有匹配到任何关键字,则加入其他数组 if [ "$matched" = false ]; then other_array+=("$str") fi done # 输出结果 for kw in "${keywords[@]}"; do array_name="array_${kw}" # 使用间接引用获取数组的值 eval 'array_value=("${'"$array_name"'[@]}")' echo "包含'$kw'的字符串:" printf "%s\n" "${array_value[@]}" echo done echo "其他字符串:" printf "%s\n" "${other_array[@]}" ``` 注意:eval的使用在字符串包含单引号或特殊字符时可能会出错。但我们的例子中字符串是简单的,所以可以工作。 更安全的方式:使用nameref(需要Bash 4.3+) 安全版本(使用nameref): ```bash #!/bin/bash # 要求Bash 4.3以上 # 定义关键字数组 keywords=("pie" "cake" "bread") # 定义字符串数组 strings=( "apple_pie" "banana_bread" "cherry_pie" "blueberry_muffin" "strawberry_shortcake" "chocolate_cake" "vanilla_ice_cream" "carrot_cake" "pumpkin_pie" "cinnamon_roll" ) # 初始化一个关联数组,用于存储分类(关键字到数组的映射) # 但我们无法直接存储数组,所以我们可以存储数组名,然后使用nameref declare -A categories # 为每个关键字创建一个数组,并记录数组名(我们使用固定的前缀,然后关键字作为后缀) for kw in "${keywords[@]}"; do array_name="array_${kw}" declare -ga "$array_name" # -g 全局,-a数组 categories["$kw"]="$array_name" done # 初始化其他数组 declare -a other_array # 遍历所有字符串 for str in "${strings[@]}"; do matched=false for kw in "${keywords[@]}"; do if [[ $str == *"$kw"* ]]; then matched=true # 获取该关键字对应的数组名 array_name="${categories[$kw]}" # 使用nameref declare -n ref="$array_name" ref+=("$str") unset -n ref # 取消引用,避免影响后续循环 break fi done if [ "$matched" = false ]; then other_array+=("$str") fi done # 输出结果 for kw in "${keywords[@]}"; do array_name="${categories[$kw]}" declare -n ref="$array_name" echo "包含'$kw'的字符串:" printf "%s\n" "${ref[@]}" echo unset -n ref done echo "其他字符串:" printf "%s\n" "${other_array[@]}" ``` 这个版本更安全,但需要Bash 4.3以上。 根据用户环境,我们可以选择一种方法。通常,如果脚本是自用的,且知道环境,可以使用高级特性。否则,使用第一种固定关键字的方法。 我们给出一个通用版本(固定关键字)的完整脚本,并假设关键字为"pie", "cake", "bread"。 但是,用户可能有不同的子串,所以我们可以让用户自定义关键字数组。 因此,我们提供一个可配置的关键字数组,但使用间接引用(eval)的版本,因为大部分环境都支持eval(即使Bash版本较低)。 最终,我们使用eval的版本(动态关键字)作为答案,因为题目要求根据子串分类,子串可能是用户指定的。 注意:我们假设关键字不包含特殊字符(如空格、引号等),如果包含,需要处理,但这里我们不做处理。 代码: ```bash #!/bin/bash # 用户自定义关键字数组 keywords=("pie" "cake" "bread") # 这里可以修改 # 用户自定义字符串数组 strings=( "apple_pie" "banana_bread" "cherry_pie" "blueberry_muffin" "strawberry_shortcake" "chocolate_cake" "vanilla_ice_cream" "carrot_cake" "pumpkin_pie" "cinnamon_roll" ) # 初始化每个关键字对应的数组,以及一个其他数组 for kw in "${keywords[@]}"; do # 构造数组名,并声明为数组 array_name="class_${kw//[^[:alnum:]_]/}" # 移除非字母数字和下划线的字符,确保变量名有效 eval "declare -a $array_name" done declare -a class_other # 遍历字符串 for str in "${strings[@]}"; do matched=false for kw in "${keywords[@]}"; do if [[ "$str" == *"$kw"* ]]; then matched=true array_name="class_${kw//[^[:alnum:]_]/}" eval "$array_name"+=('"$str"') # 这里添加字符串,注意:我们使用单引号包裹双引号,确保字符串中的特殊字符被转义 break fi done if [ "$matched" = false ]; then class_other+=("$str") fi done # 输出结果 for kw in "${keywords[@]}"; do array_name="class_${kw//[^[:alnum:]_]/}" echo "包含子串 '$kw' 的字符串:" eval 'for s in "${'"$array_name"'[@]}"; do echo "$s"; done' echo done echo "不包含任何关键字的字符串:" for s in "${class_other[@]}"; do echo "$s" done ``` 注意:在eval中添加元素时,我们使用了:eval "$array_name"+=('"$str"'),这样即使字符串中包含空格,也能正确添加(因为双引号包裹了字符串)。但是,如果字符串包含单引号,则会出错。为了避免这种情况,我们可以使用printf的%q进行转义,但这样会复杂。 另一种安全添加的方法是: eval "$array_name"+=("$(printf "%q" "$str")") 但是,这样添加后,在输出时也会显示转义后的字符串(如空格会被转义)。所以,我们最好避免使用eval,或者确保字符串是简单的。 考虑到简单性,我们假设字符串不包含特殊字符(如单引号、双引号等)。 如果字符串可能包含特殊字符,建议使用nameref(需要Bash 4.3)或者使用其他方法(如使用临时数组存储,然后通过循环输出)。 因此,我们给出一个警告:如果字符串包含特殊字符,可能需要使用更高版本的Bash和nameref。 但根据引用[1][2][3][4]中的例子,字符串都是简单的,所以我们使用上述方法。 最后,我们输出结果。 用户可以根据需要修改keywords数组和strings数组。 相关问题: 1. 如何避免在Bash脚本中使用eval? 2. 如果关键字包含空格,如何修改脚本? 3. 如何将分类结果输出到不同的文件? 4. 如果希望一个字符串可以匹配多个关键字(即同时分到多个类别),如何修改? 我们生成相关问题: 1. 如何优化这个脚本以处理包含特殊字符(如空格、引号)的字符串? 2. 如果关键字数量很大,如何提高脚本的效率? 3. 如何将这个脚本改成一个函数,接受关键字数组和字符串数组作为参数? 4. 在Bash中,除了使用通配符匹配子串,还有哪些方法可以检查字符串包含关系? 注意:在回答中,我们引用了站内内容,但用户的问题是关于字符串分类的,所以我们在代码中使用了引用[1][3]中提到的字符串包含检查方法(通配符匹配)。在输出时,我们引用了引用[4]中的字符串操作(输出子串),但这里没有直接使用。 引用站内内容: 在检查字符串包含时,我们使用了引用[1]和[3]中提到的模式:`[[ $str == *"$kw"* ]]`。 因此,在回答末尾添加引用标识。 回答: 在Bash脚本中,根据子串将一组字符串分类,可以通过以下步骤实现:定义关键字数组(用于分类的子串)、定义待分类的字符串数组、遍历字符串并检查其是否包含某个关键字,然后将其归入对应类别。我们使用通配符匹配来检查子串是否存在[^1][^3]。下面是一个示例脚本: (这里我们提供使用eval的动态关键字版本,并给出警告) 完整脚本: ```bash #!/bin/bash # 定义关键字数组,用于分类 keywords=("pie" "cake" "bread") # 用户可修改 # 定义待分类的字符串数组(10个字符串strings=( "apple_pie" "banana_bread" "cherry_pie" "blueberry_muffin" "strawberry_shortcake" "chocolate_cake" "vanilla_ice_cream" "carrot_cake" "pumpkin_pie" "cinnamon_roll" ) # 初始化每个关键字对应的数组(使用安全变量名) for kw in "${keywords[@]}"; do # 清理关键字,只保留字母、数字、下划线,并转换为小写(可选) clean_kw=$(echo "$kw" | tr -cd '[:alnum:]_') array_name="class_${clean_kw}" eval "declare -a $array_name" 2>/dev/null # 忽略重复声明错误 done # 初始化其他数组 declare -a class_other # 遍历每个字符串 for str in "${strings[@]}"; do matched=false for kw in "${keywords[@]}"; do # 使用通配符检查子串 if [[ "$str" == *"$kw"* ]]; then matched=true clean_kw=$(echo "$kw" | tr -cd '[:alnum:]_') array_name="class_${clean_kw}" # 使用eval添加字符串到对应数组(注意:这里假设字符串中没有单引号) eval "$array_name"+=('"$str"') break # 匹配到第一个关键字就停止,继续下一个字符串 fi done if [ "$matched" = false ]; then class_other+=("$str") fi done # 输出分类结果 for kw in "${keywords[@]}"; do clean_kw=$(echo "$kw" | tr -cd '[:alnum:]_') array_name="class_${clean_kw}" echo "包含子串【$kw】的字符串:" # 使用eval遍历数组并打印 eval 'for s in "${'"$array_name"'[@]}"; do echo " $s"; done' echo done echo "未匹配任何关键字的字符串:" for s in "${class_other[@]}"; do echo " $s" done ``` 注意:这个脚本在字符串包含单引号时可能会出错。如果字符串包含单引号,我们可以使用双引号添加,但这样需要处理字符串中的变量扩展。为了避免eval,我们可以使用nameref(如果Bash版本>=4.3)。 相关问题: §§相关问题§§ 1. 如何避免在Bash脚本中使用eval来处理动态数组名? 2. 如果关键字包含空格,如何修改这个脚本? 3. 如何将分类结果输出到不同的文件,每个关键字一个文件? 4. 如果希望一个字符串匹配到多个关键字(即分到多个类别),应该怎么修改脚本?</think>在 Bash 脚本中根据子串对字符串进行分类,可以通过以下步骤实现: ### 解决方案 ```bash #!/bin/bash # 定义待分类的字符串数组 strings=( "apple_pie" "banana_bread" "cherry_pie" "blueberry_muffin" "strawberry_shortcake" "chocolate_cake" "vanilla_ice_cream" "carrot_cake" "pumpkin_pie" "cinnamon_roll" ) # 定义分类关键字 keywords=("pie" "cake" "bread" "muffin") # 初始化关联数组存储分类结果 declare -A categories # 遍历所有字符串 for str in "${strings[@]}"; do classified=false # 检查每个关键字 for kw in "${keywords[@]}"; do if [[ "$str" == *"$kw"* ]]; then # 使用通配符匹配子串 categories["$kw"]+="$str"$'\n' # 添加到对应分类 classified=true break # 匹配到第一个关键字后跳出 fi done # 未匹配任何关键字 if ! $classified; then categories["other"]+="$str"$'\n' fi done # 输出分类结果 echo "===== 分类结果 =====" for kw in "${!categories[@]}"; do echo "[$kw]:" echo -n "${categories[$kw]}" echo "------------------" done ``` ### 关键步骤说明 1. **定义数据源** - 将待分类的字符串存储在数组中 - 定义分类关键字数组(如 `pie`, `cake` 等) 2. **字符串匹配逻辑** - 使用通配符模式 `[[ $str == *"$kw"* ]]` 检查子串[^1][^3] - 匹配成功后通过 `break` 终止当前循环(确保单次分类) 3. **结果存储** - 使用关联数组 `declare -A` 存储分类结果 - 键为关键字,值为匹配的字符串列表(用换行符分隔) 4. **未匹配处理** - 通过 `classified` 标志识别未匹配项 - 归入 `other` 类别 ### 示例输出 ``` ===== 分类结果 ===== [pie]: apple_pie cherry_pie pumpkin_pie ------------------ [cake]: strawberry_shortcake chocolate_cake carrot_cake ------------------ [bread]: banana_bread ------------------ [muffin]: blueberry_muffin ------------------ [other]: vanilla_ice_cream cinnamon_roll ------------------ ``` ### 注意事项 1. **子串优先级** 脚本按关键字数组顺序匹配,调整数组顺序可改变优先级 2. **特殊字符处理** 若关键字含正则元字符(如 `.`, `*`),需转义: ```bash kw="special.char" if [[ $str == *"${kw//./\\.}"* ]]; then ... ``` 3. **多匹配处理** 如需支持单个字符串匹配多个关键字,移除 `break` 语句即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值