C#中与Java的appendReplacement和appendTail相对应的是什么Regex方法?

5

更新

这是我想出来的内容。由于它是一个更大的代码片段的一部分,因此我还没有测试过。

你能看到任何看起来不对劲的地方吗?

private const string tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%";
string html = "some html";
int p = 0;
var userBlock = new ArrayList();

MatchCollection matcher = preservePatterns[p].Matches(html);
int index = 0;
StringBuilder sb = new StringBuilder();
int lastValue = 0;

foreach(Match match in matcher){
    string matchValue = match.Groups[0].Value;

    if(matchValue.Trim().Length > 0) {
        userBlock.Add(matchValue);

        int curIndex = lastValue + match.Index;
        sb.Append(html.Substring(lastValue, curIndex));
        sb.AppendFormat(tempUserBlock, p, index++);

        lastValue = curIndex + match.Length;
    }
}

sb.Append(html.Substring(lastValue));
html = sb.ToString();

以下是原始 Java 代码:
private static final String tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%";
String html = "some html";
int p = 0;
List<String> userBlock = new ArrayList<String>();

Matcher matcher = patternToMatch.matcher(html);
int index = 0;
StringBuffer sb = new StringBuffer();
while (matcher.find())
{
    if (matcher.group(0).trim().length() > 0)
    {
        userBlock.add(matcher.group(0));
        matcher.appendReplacement(sb, MessageFormat.format(tempUserBlock, p, index++));
    }
}
matcher.appendTail(sb);
html = sb.toString();

我的C#转换到目前为止:

private const string tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%";
string html = "some html";
int p = 0;
var userBlock = new ArrayList();

MatchCollection matcher = preservePattern.Matches(html);
int index = 0;
StringBuilder sb = new StringBuilder();

for(var i = 0; i < matcher.Count; ++i){
    string match = matcher[i].Groups[0].Value;
    if(match.Trim().Length > 0) {
        userBlock.Add(match);
        // WHAT DO I DO HERE?
        sb.Append( string.Format(tempUserBlock, p, index++) );            
    }
}
// WHAT DO I DO HERE?
matcher.appendTail(sb);
html = sb.toString();

请看上面的评论,在那里我问:“我在这里该做什么?”

澄清
上面的Java代码正在对一些HTML执行字符串替换。它保存了最初被替换的文本,因为需要在一些空格压缩完成后重新插入。


2
你能更好地定义问题吗?比如,期望的结果是什么,你得到的结果又是什么? - CodingGorilla
5
我猜您是在询问被标记为"// WHAT DO I DO HERE?"的部分应该怎么做? - jrummell
1
你能否发布完整的代码?如果我们不知道p或tempUserBlock是什么,很难在“我在这里该做什么”下面(我猜这就是问题),提供帮助。 - Christoph
1
从我非常有限的Java理解来看,我看到这段代码中有两个概念是不应该出现在一起的:HTML和Regex。如果这段代码正在做我认为它在做的事情(使用Regex解析HTML),我强烈建议您利用重写这段代码的机会,以正确的方式完成它,即使用像Html Agility PackSGMLReader这样的HTML解析器。忘记那些正则表达式、字符串构建器和字符串修剪。用正确的方法来做。 - Darin Dimitrov
1
@Darin,我同意你的观点;但这应该是一个快速移植已经用Java编写的HTML/CSS/Javascript压缩器。 - David Murdoch
显示剩余11条评论
2个回答

5

无需重复Java的appendReplacement/appendTail功能; .NET拥有更好的解决方案:MatchEvaluator。请查看:

string holder = "Element {0} = {1}";
string s0 = "111 222 XYZ";
ArrayList arr = new ArrayList();

string s1 = Regex.Replace(s0, @"\d+",
  m => string.Format(holder, arr.Add(m.Value), m.Value)
);

Console.WriteLine(s1);
foreach (string s in arr)
{
  Console.WriteLine(s);
}

输出:

Element 0 = 111 Element 1 = 222 XYZ
111
222

有几种实现MatchEvaluator的方法,在这篇文章中都有详细讨论。其中,lambda表达式是最酷的一种。


1
明天早上我会检查一下。+1因为基于“酷炫”的编程。 - David Murdoch

2

我不熟悉Java正则表达式类,但这是我对你的代码的C#解释:

private const string tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%"; 
string html = "some html"; 
int p = 0; 
var userBlock = new List<string>(); 

MatchCollection matcher = preservePattern.Matches(html); 
StringBuilder sb = new StringBuilder(); 
int last = 0;
foreach (Match m in matcher)
{
    string match = m.Groups[0].Value; 
    if(match.Trim().Length > 0) { 
        userBlock.Add(match); 
        sb.Append(html.Substring(last, m.Index - last));
        sb.Append(m.Result(string.Format(tempUserBlock, p, index++)));
    }
    last = m.Index + m.Length;
}
sb.Append(html.Substring(last));
html = sb.ToString(); 

1
太棒了,这几乎就是我想到的!你把 m.Index + m.Length 放在了正确的位置。谢谢。稍后我会告诉你它的表现如何。 - David Murdoch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接