- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有这段代码,我将 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()
。
您遇到的问题是您尝试引用传递的字符串和转义括号,本质上是双重转义(让人想起&
在 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/
我正在用 yacc/bison 编写一个简单的计算器。 表达式的语法看起来有点像这样: expr : NUM | expr '+' expr { $$ = $1 + $3; } | expr '-'
我开始学习 lambda 表达式,并在以下情况下遇到了以下语句: interface MyNumber { double getValue(); } MyNumber number; nu
这两个 Linq 查询有什么区别: var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault(); // vs. va
如果我们查看 draft C++ standard 5.1.2 Lambda 表达式 段 2 说(强调我的 future ): The evaluation of a lambda-expressio
我使用的是 Mule 4.2.2 运行时、studio 7.5.1 和 Oracle JDK 1.8.0_251。 我在 java 代码中使用 Lambda 表达式,该表达式由 java Invoke
我是 XPath 的新手。我有网页的html源 http://london.craigslist.co.uk/com/1233708939.html 现在我想从上面的页面中提取以下数据 完整日期 电子
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我将如何编写一个 Cron 表达式以在每天上午 8 点和下午 3:30 触发?我了解如何创建每天触发一次的表达式,而不是在多个设定时间触发。提前致谢 最佳答案 你应该只使用两行。 0 8 * * *
这个问题已经有答案了: What do 3 dots next to a parameter type mean in Java? (9 个回答) varargs and the '...' argu
我是 python 新手,在阅读 BeautifulSoup 教程时,我不明白这个表达式“[x for x in titles if x.findChildren()][:-1]”我不明白?你能解释一
(?:) 这是一个有效的 ruby 正则表达式,谁能告诉我它是什么意思? 谢谢 最佳答案 正如其他人所说,它被用作正则表达式的非捕获语法,但是,它也是正则表达式之外的有效 ruby 语法。 在
这个问题在这里已经有了答案: Why does ++[[]][+[]]+[+[]] return the string "10"? (10 个答案) 关闭 8 年前。 谁能帮我处理这个 JavaSc
这个问题在这里已经有了答案: What is the "-->" operator in C++? (29 个答案) Java: Prefix/postfix of increment/decrem
这个问题在这里已经有了答案: List comprehension vs. lambda + filter (16 个答案) 关闭 10 个月前。 我不确定我是否需要 lambda 或其他东西。但是,
C 中的 assert() 函数工作原理对我来说就像一片黑暗的森林。根据这里的答案https://stackoverflow.com/a/1571360 ,您可以使用以下构造将自定义消息输出到您的断言
在this页,John Barnes 写道: If the conditional expression is the argument of a type conversion then effec
我必须创建一个调度程序,它必须每周从第一天上午 9 点到第二天晚上 11 点 59 分运行 2 天(星期四和星期五)。为此,我需要提供一个 cron 表达式。 0-0 0-0 9-23 ? * THU
我正在尝试编写一个 Linq 表达式来检查派生类中的属性,但该列表由来自基类的成员组成。下面的示例代码。以“var list”开头的 Process 方法的第二行无法编译,但我不确定应该使用什么语法来
此 sed 表达式将输入字符串转换为两行输出字符串。两条输出行中的每一行都由输入的子串组成。第一行需要转换成大写: s:random_stuff\(choice1\|choice2\){\([^}]*
我正在使用 Quartz.Net 在我的应用程序中安排我的工作。我只是想知道是否可以为以下场景构建 CRON 表达式: Every second between 2:15AM and 5:20AM 最
我是一名优秀的程序员,十分优秀!