Java 正则表达式-如何匹配元素,同时忽略引号之间的其他元素?
我似乎找不到适合我需要的正则表达式 我有此表单的.txt文件:Java 正则表达式-如何匹配元素,同时忽略引号之间的其他元素?,java,regex,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+”匹配的所有内容,引号之间的除外 我想重命名每个单词(引号中的单词除外),因
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"
使用正则表达式甚至可以实现这一点吗?有没有不使用正则表达式的替代方法?一个简单的方法可能是将字符串拆分为
“
,然后在每个奇数部分上使用正则表达式进行替换(在第1部分、第3部分,…,如果从1开始编号),然后将所有内容重新连接
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
?如果是,则您需要更高级的解析器,或者您可能会考虑使用某种特殊格式。您无法按照您可能的想法制定“带引号”条件。但是您可以轻松搜索未引号的单词或带引号的字符串,并仅对未引号的单词采取操作:
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
)。如果引号是平衡的,并且输入中没有转义,如\”
,则可以使用此正则表达式匹配双引号外的单词:
(?=(?:(?:[^"]*"){2})*[^"]*$)(\b[a-zA-Z]\w+\b)
在java中,它将是:
Pattern p = Pattern.compile("(?=(?:(?:[^\"]*\"){2})*[^\"]*$)(\\b[a-zA-Z]\\w+\\b)");
如果这些单词在双引号之外,则此正则表达式将通过使用前瞻确保每个匹配单词后面有偶数个引号来匹配这些单词。根据您的文件格式,您似乎更希望重命名冒号之前的内容(
:
)这比以不同的方式处理引号内和引号外的所有内容更容易。这是一个准确的评估吗?埃塔:帖子已经更新,这个问题现在无关紧要,因为这显然不是一个准确的评估。这是Json吗?因为Json格式更易编译。你最好使用一个库来这个。好的,我用文件格式做了一个小编辑。我用java来完成这个任务。不,它不是Json。Abc
变成a
,Brooking变成Z
?这是一个非常复杂的正则表达式。是的,这是我的想法。这正是我一直在寻找的,非常感谢。你刚刚帮了我一个大忙t、 (是的,引号是平衡的)