将特定字符串解析为所需的输出

时间:2013-11-19 10:13:25

标签: java regex

我在主法中提到了2个案例。

* 如果1 * 匹配方法正在返回我想要的但是

案例2 返回空列表。

请帮我提供一个可以在两种情况下都能使用的通用正则表达式。 示例输入字符串:

"\"NB_DAY_DIM\".\"MONTH_YEAR\"+\"l\".\"m\""

期望的o / p:

[{column = MONTH_YEAR,value =" NB_DAY_DIM"。" MONTH_YEAR",table = NB_DAY_DIM},{column = m,value =" l"。 " m",table = l}]

public static List<Map<String, String>> match(String source) {
String pattern = "\"(.*?)\".\"(.*?)\"";


    List<Object> list = new ArrayList<Object>();

    Pattern r = Pattern.compile(pattern);
    Matcher m = r.matcher(source);

    while (m.find()) {

        Map<String, String> mp = new HashMap<String, String>();
        mp.put("value", m.group(0));
        mp.put("table", m.group(1));
        mp.put("column", m.group(2));

        list.add(mp);
        source = source.replace(m.group(0), "");
        m = r.matcher(source);
    }

    return list;
}

public static void main(String[] args) {
    System.out.println(match("\"NB_DAY_DIM\".\"MONTH_YEAR\"+\"l\".\"m\""));//case 1
    System.out.println(match("NB_DAY_DIM.MONTH_YEAR+l.m"));//case 2
}
NB_DAY_DIM.MONTH_YEARl.m之间的

运算符可以是算术或逻辑运算符,如"NB_DAY_DIM.MONTH_YEAR-l.m" 它也可以有像NB_DAY_DIM.MONTH_YEAR+l.m-xyz.abc*l.m

这样的重复模式

1 个答案:

答案 0 :(得分:2)

如果引号完全是可选的,请尝试使用此表达式(非Java表示法):

"?([^+"]+)"?\."?([^+"]+)"?

简短分类:

  • "?表示可选引号
  • ([^+"]+)表示至少一个不是加号或引号的字符序列
  • 因此,完整表达式意味着“至少一个字符的两个序列,它们不是加号或引号,用点分隔并用可选的引号括起来。

<强>更新

这是“所有引号或无引号”的表达式:

(?<=\+|^)("?)([^+"]+)\1\.\1([^+"]+)\1(?:\+|$)

变化是:

  • 第1组现在是引号,因此您必须更改读取qroups的代码
  • \1是对第一组的反向引用,即如果找到第一个引号,则所有其他引号也必须在那里,如果没有,则不允许使用引号。
  • (?=\+|$)用于定义匹配必须后跟输入的加号或结尾。这需要拒绝仅具有尾随引号的情况,例如, NB_DAY_DIM.MONTH_YEAR"
  • 同样(?<=\+|^)用于防止仅具有前导引号的情况,例如"NB_DAY_DIM.MONTH_YEAR+l.m

此表达式匹配

  • NB_DAY_DIM.MONTH_YEAR+"l"."m"
  • "NB_DAY_DIM"."MONTH_YEAR"+"l"."m"
  • NB_DAY_DIM.MONTH_YEAR+l.m
  • 等。

但不是

  • "NB_DAY_DIM.MONTH_YEAR+"l"."m"
  • NB_DAY_DIM."MONTH_YEAR"+"l"."m"
  • NB_DAY_DIM.MONTH_YEAR"+l.m
  • 等。

更新2:,因为评论说分隔符可以是任何算术运算符,只需展开不允许的字符以包含它们,例如而不是[^+"]使用[^+\-*/"]。另外,将后视/前瞻从\+|^扩展为[+\-*/]|^

这是一个扩展的表达式,如果有其他要求,可以随意添加它们:

(?<=[+\-*/]|^)("?)([^+\-*/"]+)\1\.\1([^+\-*/"]+)\1(?=[+\-*/]|$)

这将匹配NB_DAY_DIM.MONTH_YEAR+l.m-xyz.abc*l.m

更新3:

为了从字符串中提取<table>.<column>对,您可以使用如下表达式:

"?(\w+)"?\."?(\w+)"?

请注意,这并不能确保所有引号都设置为或者没有设置,并且它还假设您仅使用单词字符(即[a-zA-Z0-9_])作为表名和列名。

然而,它可能符合您的目的。

如果您需要其他帮助,请提出新问题,不要将其全部放入此问题中。我建议深入研究正则表达式语法(一个好的来源是http://regular-epxressions.info),如果你需要更频繁的话(并且总是很有用)。

关于正则表达式的最后一个注释:并非所有问题都可以通过正则表达式得到最好的解决(甚至可以解决)。你的例子开始变得越来越复杂,似乎你实际上是在尝试编写一些解析器。正则表达式在这里使用有限。