Java 如何使用正则表达式计算元素相对于另一个元素的位置?

Java 如何使用正则表达式计算元素相对于另一个元素的位置?,java,regex,Java,Regex,给定字符串 // 1 2 3 String a = "letters.1223434.more_letters"; 我想知道数字排在第一个点之后的第二位 然后,我想用这些知识来代替“第二个职位” 用“你好”来有效地使 // 1 2 3 String b = "someWords.hello.morewords"; 必须根据字符串a中匹配元素的原始位置进行替换 请问如何使用正则表达式实现这一点?字符串a的正则表

给定字符串

//          1       2       3
String a = "letters.1223434.more_letters";

我想知道数字排在第一个点之后的第二位

然后,我想用这些知识来代替“第二个职位”

用“你好”来有效地使

//          1         2     3
String b = "someWords.hello.morewords";
必须根据字符串a中匹配元素的原始位置进行替换


请问如何使用正则表达式实现这一点?

字符串a的正则表达式是

\w+\.(\d+)\.\w+ 
使用匹配组获取号码

第二个正则表达式是

\w+\.(\w+)\.\w+
获取第二个字符串的匹配组

然后使用这样的代码来处理匹配项

Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(inputStr);
boolean matchFound = matcher.find();
其中patternStr是我上面提到的模式,inputStr是输入字符串


您可以使用它的变体来尝试您想要的每个组合。所以你可以把比赛组移到第一个位置,试试看。如果返回匹配,则在第一个位置的第二个字符串中进行替换。如果没有,请转到位置2,依此类推…

您想在RegExp中直接执行的操作是不可能的,因为您无法访问捕获组的编号并在替换操作中使用该编号

两个备选方案:

  • 如果您可以使用任何编程语言:使用regexp将一个文件拆分为多个组。检查每个组是否符合您的数字标识符条件。将b字符串拆分为组。替换相应的匹配项

  • 如果您只想使用多个regexp,那么可以使用唯一的分隔符(比如|)连接a和b。然后匹配
    *?\。\d+?\..*?**?*。(.*?\..*?
    并替换
    $1
    。您需要将此regexp应用于三种变体:第一位置、第二位置和第三位置


要查找这些数字,可以使用组机制(常规表达式中的圆括号):

regex
告诉您搜索两个点(包括这些点)之间的所有字符,因此
替换应为“.hello”(带点)

如果字符串有更多的点,它将替换第一个点和最后一个点之间的所有字符。如果希望正则表达式搜索满足模式所需的最小字符数,则需要使用不情愿的量词->
,如:

String b = "letters.1223434abc.more_letters.another.dots";
b=b.replaceFirst("\\.(.+?)\\.", ".hello.");//there is "+?" instead of "+"
System.out.println(b);// OUT => letters.hello.more_letters.another.dots

我不明白,你想从字符串a中提取数字吗?然后在字符串b中进行替换?我想知道数字(比如我匹配数字)位于第二位。然后,知道了这一点,我想从另一个同样位于第二个位置的字符串中提取一些东西,如果模式匹配第一个单词呢?第一个单词前面没有点,因此您的
“.word.”
逻辑将失败。提示:使用“环顾四周”regex@Bohemian从我所看到的问题来看,字符串的开头没有点,所以第一个单词不能匹配模式“dotCharsDot”。在正则表达式的开头(和结尾),我用“\\.”表示匹配字符串在begging和end处必须包含点,所以替换也必须包含这些点,否则它们在替换后会消失。我认为您的算法有缺陷。我们可以永远讨论这个问题,或者您可以运行一个测试,测试匹配的第一个单词(
“字母”
,在OP的示例中)并查看您的代码是否有效。我建议进行测试,这将立即证明/反驳我的信念。@Bohemian从你的声誉判断,我认为你是对的。但我只是一个新手,只懂Java和正则表达式的基本知识,根本不理解我的错误(无法想象字符串类似于问题中的字符串,这将为我的正则表达式生成不正确的匹配/输出)。如果您能编写一些代码示例来指出我的错误,我将不胜感激。
import java.util.regex.*;

...

String data = "letters.1223434.more_letters";
String pattern="(.+?)\\.(.+?)\\.(.+)";
Matcher m = Pattern.compile(pattern).matcher(data);
if (m.find()) //or while if needed
    for (int i = 1; i <= m.groupCount(); i++) 
    //group 0 == whole String, so I ignore it and start from i=1
        System.out.println(i+") [" + m.group(i) + "] start="+m.start(i));
// OUT:
//1) [letters] start=0
//2) [1223434] start=8
//3) [more_letters] start=16
//find ALL characters between 2 dots once and replace them 
String a = "letters.1223434abc.more_letters";
a=a.replaceFirst("\\.(.+)\\.", ".hello.");
System.out.println(a);// OUT => letters.hello.more_letters
String b = "letters.1223434abc.more_letters.another.dots";
b=b.replaceFirst("\\.(.+?)\\.", ".hello.");//there is "+?" instead of "+"
System.out.println(b);// OUT => letters.hello.more_letters.another.dots