问候,我有以下字符串的文件:
string.Format("{0},{1}", "Having \"Two\" On The Same Line".Localize(), "Is Tricky For regex".Localize());
我的目标是使用两个字符串获得匹配集:
我目前的正则表达式如下:
private Regex CSharpShortRegex = new Regex("\"(?<constant>[^\"]+?)\".Localize\\(\\)");
我的问题是第一行中的转义引号我最终停在引号处,我得到:
我们好像被夹在最大和最小的间隙之间。有什么希望吗?我有一些备份计划。你可以倒退正规吗?这会让事情变得更容易,因为我可以从“()ezilacoL开始。”
修改 澄清。这是我唯一的边缘情况。大多数情况下,字符串独自坐着:
var myString = "Hot Patootie".Localize()
答案 0 :(得分:1)
我的原始答案(在横向规则下面)有一个错误:正则表达式匹配器尝试从左到右的顺序。将[^"]
作为第一个选择允许它使用反斜杠,但是匹配的下一个字符是一个引号,这会阻止匹配继续进行。
不兼容性说明:鉴于下面的模式,perl会回溯到另一个替代方案(转义报价)并成功找到Having \"Two\" On The Same Line
案例的匹配项。
修复方法是首先尝试转义报价,然后尝试非报价:
var CSharpShortRegex =
new Regex("\"(?<constant>(\\\\\"|[^\"])*)\"\\.Localize\\(\\)");
或者如果您更喜欢at-string形式:
var CSharpShortRegex =
new Regex(@"""(?<constant>(\\""|[^""])*)""\.Localize\(\)");
允许逃跑:
private Regex CSharpShortRegex =
new Regex("\"(?<constant>([^\"]|\\\\\")*)\"\\.Localize\\(\\)");
应用一级转义以使图案更易于阅读,我们得到
"(?<constant>([^"]|\\")*)"\.Localize\(\)
也就是说,字符串以"
个字符开头和结尾,其间的所有字符都是非引号或转义引号。
答案 1 :(得分:1)
这是您需要的正则表达式:
@"""(?<constant>(\\.|[^""])*)""\.Localize\(\)"
测试程序:
使用System; 使用System.Text.RegularExpressions; 使用System.IO;
class Program
{
static void Main()
{
Regex CSharpShortRegex =
new Regex(@"""(?<constant>(\\.|[^""])*)""\.Localize\(\)");
foreach (string line in File.ReadAllLines("input.txt"))
foreach (Match match in CSharpShortRegex.Matches(line))
Console.WriteLine(match.Groups["constant"].Value);
}
}
输出:
Having \"Two\" On The Same Line
Is Tricky For regex
Hot Patootie
请注意,我使用@"..."
来避免在正则表达式中转义反斜杠。我认为这样可以更容易阅读。
答案 2 :(得分:1)
这个适用于我:
\"((?:[^\\"]|(?:\\\"))*)\"\.Localize\(\)
针对具有各种转义引号的多个字符串在http://www.regexplanet.com/simple/index.html上进行了测试。
看起来我们回答这个问题的大多数人都有同样粗略的想法,所以让我解释一下这个方法(#
之后的评论):
\" # We're looking for a string delimited by quotation marks
( # Capture the contents of the quotation marks
(?: # Start a non-capturing group
[^\\"] # Either read a character that isn't a quote or a slash
|(?:\\\") # Or read in a slash followed by a quote.
)* # Keep reading
) # End the capturing group
\" # The string literal ends in a quotation mark
\.Localize\(\) # and ends with the literal '.Localize()', escaping ., ( and )
对于C#,你需要两次逃避斜杠(凌乱):
\"((?:[^\\\\\"]|(?:\\\\\"))*)\"\\.Localize\\(\\)
标记正确指出此标记与引号之外的转义字符不匹配。所以这是一个更好的版本:
\"((?:[^\\"]|(?:\\")|(?:\\.))*)\"\.Localize\(\)
其削减的等价物:
\"((?:[^\\\\\"]|(?:\\\\\")|(?:\\\\.))*)\"\\.Localize\\(\\)
以相同的方式工作,除了它有一个特殊情况,如果遇到斜杠但它不能匹配\"
,它只是消耗斜杠和后面的字符并继续前进。
考虑到这一点,最好只在每个斜线上消耗两个字符,这实际上是Mark的答案所以我不会重复它。
答案 3 :(得分:0)
看起来您正在尝试解析代码,因此一种方法可能是动态评估代码:
var cr = new CSharpCodeProvider().CompileAssemblyFromSource(
new CompilerParameters { GenerateInMemory = true },
"class x { public static string e() { return " + input + "}}");
var result = cr.CompiledAssembly.GetType("x")
.GetMethod("e").Invoke(null, null) as string;
通过这种方式,您可以处理使用正则表达式处理极其困难的各种其他特殊情况(例如连接或逐字字符串)。
答案 4 :(得分:0)
new Regex(@"((([^@]|^|\n)""(?<constant>((\\.)|[^""])*)"")|(@""(?<constant>(""""|[^""])*)""))\s*\.\s*Localize\s*\(\s*\)", RegexOptions.Compiled);
处理简单和@“”字符串。它还考虑了转义序列。