【问题标题】:finding a character in a pattern in regular expression在正则表达式的模式中查找字符
【发布时间】:2016-11-13 06:06:38
【问题描述】:

我正在尝试在字符串中的引号内查找所有出现的等号

如果我的输入字符串是:

anything='', bob2='age=24, sex=M', dilan=24, noble1='yellow'

我希望找到我的角色如下

anything='', bob2='age=24, sex=M', dilan=24, nobel1=24
                      ^       ^

随后将其替换为

anything='', bob2='age~24, sex~M', dilan=24, nobel1=24
                      ^       ^

我尝试了以下方法来查找所有事件

'[^',].+?'

但这没有用。

【问题讨论】:

  • 您使用什么工具/语言?一个可能的答案可能取决于它。您的字符串是否总是格式正确(引号内没有转义序列)?
  • 使用的语言是 Hadoop Impala SQL。引号内没有转义序列
  • 引号内不会有任何引号。所以 param2='age='24', sex='M'' 永远不会是这个问题的合理案例

标签: regex impala


【解决方案1】:

仅通过正则表达式很难实现您的要求。

我想逐个字符地迭代字符串来实现它。

请检查下面的代码。我已经把评论放在里面了。我使用的是 Java,但您可以使用其中的算法。

public class Main {
    public static void main(String args[]){
        String input = "param1='', param2='age<b>=</b>24, sex<b>=</b>M', param3=24, param4='yellow'";
        char[] arr = input.toCharArray();
        boolean close = true;

        /**
         * Iterate the char array
         */
        for(int i = 0;i < arr.length;i++){
            if(arr[i] == '\''){

                /**
                 * Ignore the escaped ' char in ''
                 */
                if(i > 0 && arr[i - 1] == '\\'){
                    break;
                }

                /**
                 * Use close to check whether equal sign is inside the ''
                 */
                if(close){
                    close = false;
                }else{
                    close = true;
                }
            }else if(arr[i] == '='){
                if(!close){
                    arr[i] = '~';
                }
            }

            System.out.print(arr[i]);

        }
    }
}

【讨论】:

  • 谢谢。我应该更具体。使用的语言是 Impala SQL,
【解决方案2】:

试试这个:

(?<!param[\d+])=

并替换为:

~

细分: 它会寻找任何 '=' 并查看是否以 param[\d+] 开头.. 如果前面没有 param\d+ 那么它将捕获 = 符号。

那个=将被替换为~

Explanation

【讨论】:

  • 谢谢,差不多了。我应该更具体 实际的字符串可以是这样的 app='', policy_name='age=24, sex=M, sal=300', dvc_host=24, sender=''。所以我不能硬编码“参数”。
【解决方案3】:

您可以使用组通过正则表达式来做到这一点。

试试这个代码:

(?<=age)(\=)(\S+\s\w+)(\=)

然后,将第 1 组和第 3 组替换为 ~,并保持第 2 组不变:~$2~

演示:https://regex101.com/r/qxR9ty/1

更新

您可以首先按照@Maverick_Mrt 的建议使用 Negative Lookbehind,然后通过添加 | 来取消您想要排除的任何类别。 cat1|cat2

(?<!app|policy_name|dvc_host|sender|sal)\=

演示:https://regex101.com/r/qxR9ty/

【讨论】:

  • 谢谢。但是有一个问题,我不能硬编码“年龄”
  • 我无法预测 app|policy_name 硬编码等参数列表
  • @GeorgeJoseph 你能预测引号内的列表,比如性别和年龄吗?
  • Nopes 无法预测引号内的列表。但在引号内不会有任何引号
猜你喜欢
  • 2021-09-15
  • 2016-08-16
  • 1970-01-01
  • 2022-06-28
  • 1970-01-01
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多