Regex 将字符串模式与随机开始和/或结束匹配
假设我有以下构造:Regex 将字符串模式与随机开始和/或结束匹配,regex,algorithm,Regex,Algorithm,假设我有以下构造: pattern = 'RepeatingMessage' searchString = 'Aai23epjsditssageRepeatingMessageRepeatingMessageRepeatingMessageRepAsdjigrjiegj' 我怎样才能生成一个剪切的函数 'ssageRepeatingMessageRepeatingMessageRepeatingMessageRep' 可靠地,这样重复消息的开始和结束可以是随机的 因此,它也可能是: 'sfd
pattern = 'RepeatingMessage'
searchString = 'Aai23epjsditssageRepeatingMessageRepeatingMessageRepeatingMessageRepAsdjigrjiegj'
我怎样才能生成一个剪切的函数
'ssageRepeatingMessageRepeatingMessageRepeatingMessageRep'
可靠地,这样重复消息的开始和结束可以是随机的
因此,它也可能是:
'sfdsfu338843ufsingMessageRepeatingMessageRepeatingMessafuaz8792afsmssage'
在你剪的第二根弦上
'ingMessageRepeatingMessageRepeatingMessa'
提前感谢我的回答基于一个假设,即必须匹配的字符数最少 步骤1:构建一个状态机来计算匹配的字符数。此状态机将是循环的。构建此状态机时,应在数组中为每个节点编制索引。例如:
Node Nr: 0 1 2 3 4 5 6 7 8 ...
Node : R -> e -> p -> e -> a -> t -> i -> n -> g -> ...
Index:
'R' -> Node 0
'e' -> Node 1, 3, ...
然后在两种状态之间切换:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RepeatingMatcher
{
public static String match(String pattern, String input)
{
Map<Character, List<PatternNode>> index = PatternNode.buildPattern(pattern);
StringBuilder filteredInput = new StringBuilder();
for (int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
List<PatternNode> idxl = index.get(c);
if (idxl != null)
{
boolean looking = true;
for (int j = 0; looking && j < idxl.size(); j ++)
{
int matchCnt = idxl.get(j).consume(input, i, 0);
if (matchCnt >= pattern.length())
{
// - 1 because the for loop will increment it.
i += matchCnt - 1;
looking = false;
}
}
if (looking)
{
filteredInput.append(c);
}
}
else
{
filteredInput.append(c);
}
}
return filteredInput.toString();
}
private static class PatternNode
{
private final char patternChar;
private PatternNode next;
PatternNode(char patternChar)
{
this.patternChar = patternChar;
}
int consume(String s, int idx, int cnt)
{
if (patternChar == s.charAt(idx))
{
cnt = cnt + 1;
if (next != null)
{
cnt = next.consume(s, idx + 1, cnt);
}
}
return cnt;
}
static Map<Character, List<PatternNode>> buildPattern(String pattern)
{
Map<Character, List<PatternNode>> index = new HashMap<>();
char c = pattern.charAt(0);
PatternNode root = new PatternNode(c);
List<PatternNode> idxl = index.getOrDefault(c, new ArrayList<>());
index.put(c, idxl);
idxl.add(root);
PatternNode curr = root;
for (int i = 1; i < pattern.length(); i++)
{
c = pattern.charAt(i);
curr.next = new PatternNode(c);
curr = curr.next;
idxl = index.getOrDefault(c, new ArrayList<>());
index.put(c, idxl);
idxl.add(curr);
}
curr.next = root;
return index;
}
}
}
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公共类重复匹配器
{
公共静态字符串匹配(字符串模式、字符串输入)
{
映射索引=PatternNode.buildPattern(pattern);
StringBuilder filteredInput=新建StringBuilder();
对于(int i=0;i=pattern.length())
{
//-1,因为for循环将增加它。
i+=matchCnt-1;
看=假;
}
}
如果(看)
{
filteredInput.append(c);
}
}
其他的
{
filteredInput.append(c);
}
}
返回filteredInput.toString();
}
私有静态类模式节点
{
私有最终字符模式字符;
下一个是私有模式节点;
PatternNode(char patternChar)
{
this.patternChar=patternChar;
}
整数消耗(字符串s、整数idx、整数cnt)
{
if(patternChar==s.charAt(idx))
{
cnt=cnt+1;
如果(下一步!=null)
{
cnt=next.consume(s,idx+1,cnt);
}
}
返回cnt;
}
静态映射构建模式(字符串模式)
{
映射索引=新的HashMap();
字符c=模式字符(0);
PatternNode根=新PatternNode(c);
List idxl=index.getOrDefault(c,newArrayList());
指数put(c,idxl);
添加(根);
PatternNode curr=根节点;
对于(int i=1;i
好的,谢谢您的回复。我无法让java代码为我工作,但我制作了一个简单的脚本,似乎可以实现这一点。它从模式索引中向前和向后搜索,然后检出:(powershell)
该问题包含regex标记。我不会完全根据您的用例来建议这种方法,但我还是解决了它。这里是一个更简单、更可读的正则表达式,用于关键字“word”: 以下是解决问题的完整正则表达式:
((((((((((((((((R)?e)?p)?e)?a)?t)?i)?n)?g)?M)?e)?s)?s)?a)?g)?e)?(RepeatingMessage)+(R(e(p(e(a(t(i(n(g(M(e(s(s(a(g(e)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
模式是否在字符串中仅连续出现一次,或者是否可以有类似“EssagerepeatingMessageRepoooooAgerepeatingMessagere”的内容?是否有必须匹配的最小长度?例如,RepeatingMessage包含“a”,而原始字符串“Aai23epjsditssageRepeatingMessageRepeatingMessageRepeatingMessageRepAsdjigrjiegj”在第二个位置包含“a”。为什么这些不匹配?是的,让我们说最小字符是整个模式至少让我们说最小字符是整个模式。你能用你喜欢的语言给出类似的代码吗?我明白这个概念,但我可能很难实现它们。我尝试了你的代码,但无法让它工作。我做了一个脚本,现在为我做。我在一个回复中发布了它。我对它进行了测试,并修复了一些打字错误(在2或3个位置交换了输入和模式)和一个off-by-1错误。它现在运行良好,尽管我希望您能调试那么多。这很好,它可以很好地创建一个函数,为特定字符串生成正则表达式。虽然在“epeatingMessa”这样的情况下,当完整字符串没有出现时,它会失败。如果这是所需的行为,您可以将中心“+”替换为“*”
((((w)?o)?r)?d)?(word)+(w(o(r(d)?)?)?)?
((((((((((((((((R)?e)?p)?e)?a)?t)?i)?n)?g)?M)?e)?s)?s)?a)?g)?e)?(RepeatingMessage)+(R(e(p(e(a(t(i(n(g(M(e(s(s(a(g(e)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?