我似乎无法找到适合我需要的正则表达式。
我有一个这种形式的.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"
这是否可以使用正则表达式实现?有没有使用正则表达式的替代品?
答案 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)
在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
)。