替换java或kotlin上的特定(并非所有匹配项)正则表达式匹配项
例如,在正则表达式替换系统中,我有不同的正则表达式替换java或kotlin上的特定(并非所有匹配项)正则表达式匹配项,java,android,regex,kotlin,Java,Android,Regex,Kotlin,例如,在正则表达式替换系统中,我有不同的正则表达式 "([e][u][r])+" = "euros" "([e][u][r][o][s])+" = "currency" 但我想替换: 1. The longest match for all the regex occurrences if more than 2 regex are true for the same part of text 2. Just apply one time a rule for a part of text
"([e][u][r])+" = "euros"
"([e][u][r][o][s])+" = "currency"
但我想替换:
1. The longest match for all the regex occurrences if more than 2 regex are true for the same part of text
2. Just apply one time a rule for a part of text
如果我有一个与此类似的文本(文本不按行分割)
我有这样的症状:
第一行两次出现
eur = euros (first line, match 3 characters)
euros = currency (first line, match 5 characters)
我们选择最长的(欧元=货币)
第二行,一次出现
eur = euros (second line, match 3 characters)
第三行,两次出现
eur = euros (match 9 characters)
euros = currency (match 5 characters)
结果一定是
150,00 currency (because euros = currency is the longest match)
42,00 euros (because we apply eur = euros but after that we DON'T apply euros = currency because we just apply one replacement for a part of text)
12,00 eurosos
有没有办法复制这种行为
提前谢谢 这回答了原来的问题。
您可以使用函数
replace()
两次。更换的顺序很重要。
首先将最长的
“欧元”
替换为“货币”
,然后将“欧元”
替换为“欧元”
在您的情况下,只有1个替换项实际起作用。
对于
“150,00欧元”
:
结果:
150,00 currency
42,00 euros
对于“42,00欧元”
:
val s2 = "42,00 eur"
val new2 = s2.replace("euros", "currency").replace("eur", "euros")
println(new2)
结果:
150,00 currency
42,00 euros
这就是我解决问题的方法:
公共类MyClass{
静态列表_regexes=new ArrayList();
私有静态字符串解析字(字符串字){
//用于保持最佳匹配的变量。
字符串最长=”;
字符串替换=”;
//检查所有可能的更换件。
对于(替换正则表达式:_正则表达式){
//找到最长的匹配项。
模式p=Pattern.compile(“(“+regex.Source+”)+”);
匹配器m=p.Matcher(字);
//检查所有匹配项,如果其中一个比当前匹配项长,则将其存储。
while(m.find()){
字符串匹配=m.group();
if(match.length()>longest.length()){
最长=匹配;
替换=正则表达式目标;
}
}
}
//最后应用替换。
字符串结果=word.replace(最长,替换);
返回结果;
}
私有静态字符串解析(字符串文本){
//将文本拆分为单词。
List words=Arrays.asList(text.split(“”);
//应用替换。
words=words.stream().map(word->parseWord(word)).collect(Collectors.toList());
//将单词再次连接到文本。
返回字符串。join(“,words);
}
公共静态void main(字符串参数[]){
_添加(新替换(“欧元”、“货币”));
_补充条款(新的替代条款(“欧元”);
Collections.sort(_regexes);
列表数据=数组.asList(“150,00欧元”、“42,00欧元”、“12,00欧元”、“15,00欧元”);
用于(字符串文本:数据){
字符串结果=解析(文本);
System.out.println(文本+“-”+结果);
}
}
}
公共类替换实现了可比较的{
公共字符串源;
公共字符串目标;
公共替换(字符串源、字符串目标){
this.Source=Source;
这个。目标=目标;
}
@凌驾
公共内部比较(替换r){
返回r.Source.length();
}
}
我们无法分隔行,我们必须将所有文本作为一个单元进行处理。然后,它更难,因为我们必须根据匹配大小应用一个或其他规则。。。谢谢在我的回答中,我有两个例子,每种情况一个。我不把这两行分开。如果s
包含您的字符串,则s.replace(“欧元”、“货币”).replace(“欧元”、“欧元”)
在任何情况下都可以工作。例如,在这样的方向上:12,00欧元,使用replace系统,我们将获得12,00欧元[货币],因为我们获得欧元=货币,但我们与eur=欧元规则的匹配时间最长->[EureurEUR]Os您的问题没有提及您在评论中发布的任何案例。因此,您所做的是使此答案无效,并且答案已被否决。“12,00欧元”的结果应该是什么。是“12,00欧洲索”吗?那么“12,00 Euroseuroseur”呢?嗨,paul,这是因为如果两个或多个规则与文本的某些部分重合,我们需要替换最大的规则eur规则比“EURO”规则更匹配。结果将是Eurosost此实现相当不错,但如果文本没有按行分割,它仍然无法正常工作,例如List data=Arrays.asList(“150,00欧元42,00欧元12,00欧元15,00欧元Roseuroseur”);在这种情况下会发生什么?你说的是“只有最长的比赛才应该被替换”,那就是“欧洲杯”。这正是代码所做的。如果你想要不同的方式,你需要考虑如何将文本分割成适当的部分。那么,你认为如果我不将文本分割成行,就没有可能实现吗?也许你是对的,我不得不想。。。问题是,“如果文本的同一部分存在歧义,则只应替换最长的匹配项,但如果我们为文本的两个单独部分匹配两个单独的正则表达式,则必须同时替换这两个正则表达式,例如,“12,00欧元”将导致“12,00欧元”“只要规则定义正确,几乎所有事情都有一个实现。”我更改了实现,现在每个单词都进行了替换。
public class MyClass {
static List<Replacement> _regexes = new ArrayList<Replacement>();
private static String parseWord(String word) {
// Variables for holding the best match.
String longest = "";
String replacement = "";
// Check all possible replacements.
for (Replacement regex: _regexes) {
// Find the longest possible match.
Pattern p = Pattern.compile("(" + regex.Source + ")+");
Matcher m = p.matcher(word);
// Check all matches and store it if one is longer that the current one.
while(m.find()) {
String match = m.group();
if (match.length() > longest.length()) {
longest = match;
replacement = regex.Target;
}
}
}
// Finally apply the replacement.
String result = word.replace(longest, replacement);
return result;
}
private static String parse(String text) {
// Split text into words.
List<String> words = Arrays.asList(text.split(" "));
// Apply replacements.
words = words.stream().map(word -> parseWord(word)).collect(Collectors.toList());
// Join the words again to a text.
return String.join(" ", words);
}
public static void main(String args[]) {
_regexes.add(new Replacement("euros", "currency"));
_regexes.add(new Replacement("eur", "euros"));
Collections.sort(_regexes);
List<String> data = Arrays.asList("150,00 euros", "42,00 eur", "12,00 eureureuros", "15,00 euroseuroseuroseur euros eur");
for (String text: data) {
String result = parse(text);
System.out.println(text + " - " + result);
}
}
}
public class Replacement implements Comparable<Replacement> {
public String Source;
public String Target;
public Replacement(String source, String target) {
this.Source = source;
this.Target = target;
}
@Override
public int compareTo(Replacement r) {
return r.Source.length();
}
}