我需要一个用于文本替换的正则表达式.示例:要匹配的文本ABC(可以用方括号括起来),替换文本是DEF.这很基本.该复杂的是,我不希望在比赛ABC时,它是由前面的图案文字\[[\d ]+\]\.-换句话说,当一个单词之前或设置在括号中的词,随后一段时间.
以下是要匹配的源文本的一些示例,以及在进行正则表达式替换后的结果:
1. [xxx xxx].[ABC] > [xxx xxx].[ABC] (does not match - first part fits the pattern)
2. [xxx xxx].ABC > [xxx xxx].ABC (does not match - first part fits the pattern)
3. [xxx.ABC > [xxx.DEF (matches - first part has no closing bracket)
4. [ABC] > [DEF] (matches - no first part)
5. ABC > DEF (matches - no first part)
6. [xxx][ABC] > [xxx][DEF] (matches - no period in between)
7. [xxx]. [ABC] > [xxx] [DEF] (matches - space in between)
Run Code Online (Sandbox Code Playgroud)
它归结为:我如何指定前面的模式,如上所述,将阻止匹配?在这种情况下,模式会是什么?(正则表达式的C#风味)
Jer*_*man 14
你想要一个负面的后视表达.这些看起来像(?<!pattern),所以:
(?<!\[[\d ]+\]\.)\[?ABC\]?
Run Code Online (Sandbox Code Playgroud)
请注意,这不会强制ABC周围的一对匹配的方括号; 它只允许一个可选的开放式支架和一个可选的紧密支架.如果你想强制匹配一对或没有,你必须使用交替:
(?<!\[[\d ]+\]\.)(?:ABC|\[ABC\])
Run Code Online (Sandbox Code Playgroud)
这使用非捕获括号来分隔交替.如果您想要实际捕获ABC,可以将其转换为捕获组.
ETA:第一个表达式似乎失败的原因是它匹配on ABC],而不是禁止文本.开放式支架[是可选的,因此它与之不匹配.解决这个问题的方法是将可选的开放式支架[转换为负面的后置断言,如下所示:
(?<!\[[\d ]+\]\.\[?)ABC\]?
Run Code Online (Sandbox Code Playgroud)
它匹配和不匹配的一个例子:
[123].[ABC]: fail (expected: fail)
[123 456].[ABC]: fail (expected: fail)
[123.ABC: match (expected: match)
matched: ABC
ABC: match (expected: match)
matched: ABC
[ABC]: match (expected: match)
matched: ABC]
[ABC[: match (expected: fail)
matched: ABC
Run Code Online (Sandbox Code Playgroud)
试图使一个开放式支架的存在[迫使一个匹配的紧密支架],如第二个模式所预期的那样,比较棘手,但这似乎有效:
(?:(?<!\[[\d ]+\]\.\[)ABC\]|(?<!\[[\d ]+\]\.)(?<!\[)ABC(?!\]))
Run Code Online (Sandbox Code Playgroud)
它匹配和不匹配的一个例子:
[123].[ABC]: fail (expected: fail)
[123 456].[ABC]: fail (expected: fail)
[123.ABC: match (expected: match)
matched: ABC
ABC: match (expected: match)
matched: ABC
[ABC]: match (expected: match)
matched: ABC]
[ABC[: fail (expected: fail)
Run Code Online (Sandbox Code Playgroud)
这些示例是使用以下代码生成的:
// Compile and run with: mcs so_regex.cs && mono so_regex.exe
using System;
using System.Text.RegularExpressions;
public class SORegex {
public static void Main() {
string[] values = {"[123].[ABC]", "[123 456].[ABC]", "[123.ABC", "ABC", "[ABC]", "[ABC["};
string[] expected = {"fail", "fail", "match", "match", "match", "fail"};
string pattern = @"(?<!\[[\d ]+\]\.\[?)ABC\]?"; // Don't force [ to match ].
//string pattern = @"(?:(?<!\[[\d ]+\]\.\[)ABC\]|(?<!\[[\d ]+\]\.)(?<!\[)ABC(?!\]))"; // Force balanced brackets.
Console.WriteLine("pattern: {0}", pattern);
int i = 0;
foreach (string text in values) {
Match m = Regex.Match(text, pattern);
bool isMatch = m.Success;
Console.WriteLine("{0}: {1} (expected: {2})", text, isMatch? "match" : "fail", expected[i++]);
if (isMatch) Console.WriteLine("\tmatched: {0}", m.Value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3233 次 |
| 最近记录: |