正则表达式 - 如何匹配元素而忽略引号之间的其他元素?

时间:2015-05-26 14:44:04

标签: java regex

我似乎无法找到适合我需要的正则表达式。

我有一个这种形式的.txt文件:

Abc "test" aBC : "Abc aBC" 
Brooking "ABC" sadxzc : "I am sad"
asd : "lorem"
a22 : "tactius"
testsa2 : "bruchia"
test : "Abc aBC"
b2 : "Ast2"

从这个.txt文件我希望提取与此正则表达式匹配的所有内容“([a-zA-Z] \ w +)”,但引号之间除外。

我想重命名每个单词(引号中的单词除外),所以我应该有以下输出:

A "test " B : "Abc aBC" 
Z "ABC" X : "I am sad"
Test : "lorem"
F : "tactius"
H : "bruchia"
Game : "Abc aBC"
S: "Ast2"

这是否可以使用正则表达式实现?有没有使用正则表达式的替代品?

3 个答案:

答案 0 :(得分:1)

一种简单的方法可能是将字符串分割为",然后在每个奇数部分使用正则表达式进行替换(如果从1开始编号,则在部分1,3,...上),并加入一切。

<强> UPD 但是,手动实现也很简单。只需沿着这条线走,并跟踪你是否在引号内。

insideQuotes = false
result = ""
currentPart = ""
input = input + '"' // so that we do not need to process the last part separately
for ch in string
    if ch == '"'
        if not insideQuotes
            currentPart = replace(currentPart)
        result = result + currentPart + '"'
        currentPart = ""
        insideQuotes = not insideQuotes
    else 
        currentPart = currentPart + ch
drop the last symbol of result (it is that quote mark that we have added)

但是,还要考虑是否需要更高级的语法。例如,引用转义为

word "inside quote \" still inside" outside again

?如果是,那么您将需要更高级的解析器,或者您可能会想到使用某种特殊格式。

答案 1 :(得分:1)

如果引号是平衡的,并且输入中没有像\"那样的转义,那么您可以使用此正则表达式来匹配双引号之外的单词:

(?=(?:(?:[^"]*"){2})*[^"]*$)(\b[a-zA-Z]\w+\b)

RegEx Demo

在java中它将是:

Pattern p = Pattern.compile("(?=(?:(?:[^\"]*\"){2})*[^\"]*$)(\\b[a-zA-Z]\\w+\\b)");

如果这些正则表达式在双引号之外,则使用前瞻来确保在每个匹配的单词后面都有偶数引号。

答案 2 :(得分:0)

您无法按照您的想法制定“引号内”条件。但是,您可以轻松搜索未引用的单词引用的字符串,并仅对未加引号的单词执行操作:

Pattern p = Pattern.compile("\"[^\"]*\"|([a-zA-Z]\\w+)");
for(String s: lines) {
    Matcher m=p.matcher(s);
    while(m.find()) {
        if(m.group(1)!=null) {
            System.out.println("take action with "+m.group(1));
        }
    }
}

这利用了下一场比赛的每次搜索都从前一场比赛开始的事实。因此,如果您找到带引号的字符串("[^"]*"),则不会采取任何操作并继续搜索其他匹配项。仅当引用字符串不匹配时,模式才会查找单词(([a-zA-Z]\w+)),如果找到一个单词,则组1将捕获该单词(将为非null)。