gpt4 book ai didi

java - 正则表达式从输入字符串中提取表达式

转载 作者:行者123 更新时间:2023-12-01 18:19:56 24 4
gpt4 key购买 nike

我正在尝试使用正则表达式从输入字符串中提取“操作数运算符操作数”格式的表达式。操作数可以是任何单个单词或引用的短语,操作数之间的运算符将是波浪号后跟数字。该表达式可能在输入字符串中出现 n 次。我的正则表达式出了什么问题?

package test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExpressionExtractor {

private static final String operator = "\\s+\\~{1}\\d+\\s+";
private static final String quotedWords = "[\"|'|“][A-Za-zÀ-ü0-9\\\\.\\/\\-,\\*\\s]+[\"|'|“]";
private static final String singleWords = "[A-Za-zÀ-ü0-9\\\\.\\/\\-,\\*]+";
private static final String operand = quotedWords+"|"+singleWords;
private static final Pattern expressionPattern = Pattern.compile("("+operand + operator +operand+")");
private static final Pattern operatorPattern = Pattern.compile(operator);

public static Matcher evaluateExpression(String input) {
return expressionPattern.matcher(input);
}
}

具有预期结果的测试用例:

package test;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;

import org.junit.Test;

public class ExpressionExtractorUnitTest {

@Test
public void testExpressionExtractor() {
assertEquals(Arrays.asList("firstWord ~20 secondWord"), find("any word firstWord ~20 secondWord one more word"));
assertEquals(Arrays.asList("mother-in-law ~8 long-Word"), find("start of sentence mother-in-law ~8 long-Word one sentence"));
assertEquals(Arrays.asList("firstWord ~7 secondWord", "word ~8 \"complex expression\""),
find("more complex expression firstWord ~7 secondWord with another word ~8 \"complex expression\" continued"));
}

private List<String> find(String expression) {
Matcher matcher = ExpressionExtractor.evaluateExpression(expression);
List<String> tokens = new ArrayList<>();
while (matcher.find()) {
tokens.add(matcher.group());
}
return tokens;
}
}

最佳答案

由于您的代码包含一个很好的单元测试,因此建议修复/更改:

  • 如果字符数为 1,则无需指定字符数,因此“~{1}”可以变为“~”。您不需要转义波浪号字符,因此“\s+\~{1}\d+\s+”可以变为“\s+~\d+\s+”。如果您不喜欢“尖桩篱笆”,您可以使用其他字符,例如这样
String operator = "!s+~!d+!s+".replace('!','\\').
  • 我发现引用词的表达太复杂,难以理解。您可以尝试使用一个以引号字符开头的组,后跟 0 个或多个非引号字符,然后再跟一个引号。另外,您不需要方括号内的管道
String quotedWords = "[\"|'|“][^\"|'|“]*[\"|'|“]";
  • 为了匹配许多替代模式,您必须为每个组添加额外的括号
expressionPattern = Pattern.compile("(" + operand + ")(" +operator + ")(" +operand + ")");

这将使测试通过。但是,您可能会考虑使用像 ANTLR 这样的语法解析器库。在那里你可以轻松地进入嵌套表达式并获取抽象语法树(AST)

关于java - 正则表达式从输入字符串中提取表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60308424/

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