gpt4 book ai didi

java - 从文件读取字符串并将其转换为文字正则表达式

转载 作者:行者123 更新时间:2023-12-01 13:27:54 27 4
gpt4 key购买 nike

我有这段代码,我将 Pattern 键和 String 标记插入到 HashMap 中:

while( (word = reservedWordsRead.readLine()) != null ) {
String[] k = word.split(" ");
infoList.put(Pattern.compile("^("+k[0]+")"), //lexeme
k[1]); //token
}

它从如下文件中读取:

) rparen
( lparen

但是括号无法识别,所以我将文件修改为如下所示:

\\) rparen
\\( lparen

代码如下:

while( (word = reservedWordsRead.readLine()) != null ) {
String[] k = word.split(" ");
infoList.put(Pattern.compile("^("+Pattern.quote(k[0])+")"), //lexeme
k[1]); //token
}

但我没有得到正确的输出。它不匹配任何东西。此外,rparen 和 lparen 被插入到 HashMap 中,因为我能够使用我的 tokenizer() 方法打印以下内容:

pattern: ^(\Q\\)\E), token: rparen
pattern: ^(\Q\\(\E), token: lparen

这是我的标记器方法:

public void tokenize(String str) {
String s = str.trim();
tokenList.clear();

while (!s.equals("")) {
boolean match = false;
for ( Entry<Pattern,String> thing: infoList.entrySet() ) {
System.out.println("pattern: "+thing.getKey().toString()+", token: "+thing.getValue());
Matcher m = thing.getKey().matcher(s);
if (m.find()) {
match = true;
String tok = m.group().trim();
s = m.replaceFirst("").trim();
tokenList.put(tok,thing.getValue());
break;
}
} if (!match)
throw new ParserException("Unexpected character in input: "+s);
}
}

我不确定我做错了什么。很高兴感谢您的帮助:)

最佳答案

如果你想匹配精确的字符串,你应该使用Pattern.quote()

您遇到的问题是您尝试引用传递的字符串转义括号,本质上是双重转义(让人想起&amp;在 HTML 中)。虽然您可以将所有特殊转义字符放入输入文件中,但为什么还要麻烦呢?让Pattern 为您完成工作。

这是一个测试,我们尝试几种不同的输入,并尝试将它们转换为模式,就像您一样。

import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class RegexTest
{
private static final String[] TESTS = {"a","(","\\(","\\\\(","[letters]"};

public static void main(String[] args) {
for(String test : TESTS) {
examineRegex(test);
System.out.println();
}
}

public static void examineRegex(String match) {
System.out.println("Testing "+match);
String template = "^(%s)";
String regex = String.format(template, match);
examinePattern(match, regex);
String quotedRegex = String.format(template, Pattern.quote(match));
examinePattern(match, quotedRegex);
}

public static void examinePattern(String match, String regex) {
try {
Pattern pattern = Pattern.compile(regex);
System.out.println(" Compiled: "+pattern);
System.out.println(" Match?: "+pattern.matcher(match).matches());
} catch (PatternSyntaxException e) {
System.out.println(" Failed to compile: "+e.getMessage()
.substring(0, e.getMessage().indexOf('\n')));
}
}
}

该程序的输出如下(内嵌注释):

Testing a
Compiled: ^(a)
Match?: true
Compiled: ^(\Qa\E)
Match?: true

对于“普通”字符串的简单情况,您的原始方法和使用 Pattern.quote() 都有效。到目前为止一切顺利。

Testing (
Failed to compile: Unclosed group near index 4
Compiled: ^(\Q(\E)
Match?: true

但是如果我们传入一个构造,例如 (,我们会得到一个错误,除非我们引用它。

Testing \(
Compiled: ^(\()
Match?: false
Compiled: ^(\Q\(\E)
Match?: true

如果我们传入转义构造,原始模式会成功编译,但它与输入字符串不匹配。这不是世界末日 - 它会匹配 ( - 但它是违反直觉的;它破坏了传入的内容就是我们匹配的期望。

Testing \\(
Failed to compile: Unclosed group near index 6
Compiled: ^(\Q\\(\E)
Match?: true

现在我们对模式进行双重转义,就好像尝试将输入视为 Java 字符串一样。这表明在尝试确定到底有多少需要转义时可能会出现困惑。

Testing [letters]
Compiled: ^([letters])
Match?: false
Compiled: ^(\Q[letters]\E)
Match?: true

最后,假设我们想要匹配一个也是实际正则表达式的字符串?它将成功编译,因此无法提醒我们问题,但无法匹配预期的字符串。

如您所见,Pattern.quote() 每次都有效,并且避免需要将正则表达式的实现细节放入数据文件中。这样,您就可以从文本文件中隐藏匹配实际发生方式的实现细节,这种划分可以产生健壮的代码。

当然,如果您在文件中想要是正则表达式列表,那么您显然不想使用Pattern.quote(),并且您相反,需要让用户明确期望输入必须是有效的 Java 正则表达式,并且提供不良模式可能会产生潜在的困惑结果。

关于java - 从文件读取字符串并将其转换为文字正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21714742/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com