【问题标题】:Turning a <input type=radio> into a <button> with Regex/C#使用 Regex/C# 将 <input type=radio> 变成 <button>
【发布时间】:2010-11-23 21:37:16
【问题描述】:

奇怪的问题,但我不会浪费时间解释为什么我需要这样做,只是我需要这样做。

我有以下几点:

<input type="radio" name="eq_9" id="eq_9_2"  onclick="nextStepID_load(this);" value="Installer." title="912" /><label for="eq_9_2">Installer</label> <br />

我需要把它变成:

<button type="button" name="eq_9" id="eq_9_2" onclick="nextStepID_load('912');">Installer</button><br />

我正在使用 C#/asp.net(3.5 或更低版本)和用于 performJS 的 javascript(这是一个占位符,直到我弄清楚如何替换 html)。

请注意,提供此信息的来源正在向我发送一个包含许多输入行的字符串。我需要用对其有效的信息替换每一行。

现在,我尝试添加一个 .Replace("","\">"); 它确实替换了无线电标签,但显然它在代码方面看起来很糟糕,并且不会删除标签或放置标签之间的标签内容。

我确信这可能最好通过正则表达式来解决,但我对正则表达式不是很熟悉。我一直在玩 regexlib,看看我是否可以自己找出一个正则表达式......这是我到目前为止所拥有的,虽然我想我还很遥远。

string strRegex = @"<input type=""radio"" [\s]*=[\s]*""?[^\w_]*""?[^>]*>";
RegexOptions myRegexOptions = RegexOptions.IgnoreCase | RegexOptions.Multiline;
Regex myRegex = new Regex(strRegex, myRegexOptions);
string strTargetString = @"<input type=""radio"" name=""eq_9"" id=""eq_9_2""  onclick=""nextStepID_load(this);"" value=""Installer."" title=""912"" /><label for=""eq_9_2"">Installer</label> <br />";
string strReplace = "<button type="button"></button>";
return myRegex.Replace(strTargetString, strReplace);

【问题讨论】:

  • 哦!哦!轮到我发布这个链接,详细说明使用正则表达式解析 HTML 的愚蠢之处:stackoverflow.com/questions/1732348/…
  • 这似乎是具有众所周知特征的固定 HTML。如果这是真的,那么用正则表达式解析是微不足道的,你可能应该简单地这样做。真正的问题是它实际上是如何固定的,以及什么去哪里了。
  • @tchrist:当然,他的小例子看起来像固定的 html,我确信他收到的文档格式正确(谁知道什么规范),我同样确定某个地方您可以构建一个 reg ex 来解析示例(这次)。但归根结底,Friends 不会让 Friends 混合 RegEx 和 HTML。永远。
  • @Chris:我对在 HTML 我自己生成的上使用正则表达式没有任何疑虑。在其他人的情况下,嗯,那是我开始感到不安的时候。
  • @Chris:再加上为了诚实而牺牲谦虚的风险,I 发现使用正则表达式可行的集合可能比这个用户发现的要大得多,考虑到像@这样的东西987654322@ 和 thisthis。明白了吗? :)

标签: c# asp.net regex


【解决方案1】:

不要使用正则表达式来处理 HTML。它仅对 95% 的情况足够灵活,这应该告诉您它是不适合这项工作的工具。

使用HTML Agility Pack,您可以加载您的文档并使用类似的东西来替换...

HtmlDocument doc = new HtmlDocument();
doc.Load(@"C:\Path\To\Page.html");

HtmlNode radios = doc.SelectNodes("//input[@type=radio]");

foreach (HtmlNode node in radios)
{
    HtmlAttribute name = node.Attributes["name"];

    if (name != null && name.ToLower().StartsWith("eq_"))
    {
        //Build your button element and replace the radio using ReplaceChild
    }
}

【讨论】:

  • 谢谢,我明天去看看。看起来很有希望。如果成功,将更新帖子。
【解决方案2】:

我确信这可能最好通过正则表达式来解决,但我对正则表达式不是很熟悉。

恐怕这不是一个好兆头,因为如果您对正则表达式不是很熟悉,那么 anything 不太可能最好通过正则表达式来解决。 :(

没有足够的问题描述来确定是否即使是正则表达式向导也可以使用正则表达式快速制定解决方案。我很确定您需要做的不仅仅是将一个固定字符串交换为另一个,因为如果您这样做了,那么您已经这样做了。所以它的一部分必须参数化。我只是不知道是哪个。

不算空格,你会说你的问题是转换这种形式的输入之一吗:

<input 
    type="radio"
    name="eq_X"
    id="eq_X_Y"
    onclick="nextStepID_load('XNY');"
    value="Z."
    title="XNY"  
/>
<label for="eq_X_Y"> Z </label>
<br />

进入这种形式的输出:

<button 
    type="button" 
    name="eq_X" 
    id="eq_X_Y" 
    onclick="nextStepID_load('XNY');" 
>
Z
</button>

<br />

如您所见,我已经参数化了 XYZN。以下是我要问你的问题:

  1. 您会说我对您问题的参数化描述准确吗?

  2. 这是否在某些特定的 DTD 下有效,如果有效,是哪一个?

  3. 属性是否总是这些?

  4. 出现的属性是否总是以精确的顺​​序出现?

  5. 你需要做多少这样的事情?

  6. 这是发生在纯 HTML 中,还是实际上隐藏在某些 Javascript 中?

  7. 您知道是否有任何 &lt;script&gt;&lt;style&gt; 元素或 &lt;!-- ... --&gt; cmets 包含看起来正是您正在寻找的东西?

  8. 你知道在你正在寻找的东西中间是否有任何这样的元素吗?

  9. NAME="VALUE" 形式的所有属性的值是否只有双引号,从不单引号或完全省略?

  10. 标识符的大小写是否总是小写?

  11. 它们都在一个文件中吗?

  12. 是否有某些原因导致您的输出样本丢失了一些不重要的空白?

正是这样的问题说明了为什么问题几乎肯定比看起来要复杂得多——这引出了几个最后的问题:

  1. 您以前使用过 HTML 解析类吗?

  2. 您想了解如何操作吗?

【讨论】:

  • +1。我认为您单独提出的问题应该使您得出关于使用 HTML 解析器的结论。这是 OP 面临的问题空间的一个很好的总结。
  • 2) 使用 xHTML 1.0 过渡。 3) 这些总是包含在每个元素/属性中的顺序和一般数据。 4) 是的。 5) 这是基于当前步骤的动态量。但我总是需要处理所有这些,无论是 1 还是 1000。 6) C# 类将此(html 代码)作为字符串返回到我要更改的页面。 7) 所有都在 C# 类上解析,我无法编辑,也无法从进程中删除。 8) 在将 html 作为字符串传回之前,我永远不会使用这些属性。
  • 9) 格式如前所述(实际示例)。 10) 是的。同样,总是包含相同的格式,只是不同的属性数据。 11) 一个字符串,传回页面。 12) 返回数据的属性之外没有空格。 _______ 第 2 部分 1) No. 2) 愿意学习新技巧
  • @JClaspill:我希望你考虑使用解析类。我通常会为此给你写一个正则表达式,但我已经在上游划了一段时间了:我刚刚花了太多时间重新实现\w,\W,\d,@ 987654330@,\s,\S, \b,\B, \p{Space}, \p{Alpha}, \p{Hyphen},\p{Dash}, 和 \p{QMark} 对于 Java,因为它们都是在 Java 的标准 Pattern 类中完全损坏或完全缺失。 Java 中的正则表达式——尤其是 Unicode——太像试图教猪唱歌:它浪费你的时间并且惹恼了猪。它也会让你周围的每个人感到厌烦。
【解决方案3】:

本练习使用正则表达式完成您需要的工作。

它是这样工作的: 我不替换原始字符串中的值。相反,我采用目标字符串,我们想要到达的地方,并用正确的值构建它。 我相信这种方法会给您带来灵活性,您可以根据需要格式化输出字符串。

  • inputList 是一个测试列表 案例。
  • 目标就是目标 带占位符的字符串,我们可以格式化它但是我们 想要/需要/不得不。
  • GetValue() 方法利用正则表达式参数来寻找特定值。它将 html 标记查找为 KeyValue 对,获取 Value 并删除封闭的引号。
  • 最后使用 string.Format() 我们根据需要构建输出字符串。

这是完整的代码,所以你可以试试。您还可以将这段代码的想法转化为一种方法,并将其集成到您的解决方案中。

如果它也对你有用,请告诉我。

      static void Main(string[] args)
    {

        List<string> inputList = new List<string>();
        inputList.Add("<input type=\"radio\" name=\"eq_9\" id=\"eq_9_2\"  onclick=\"nextStepID_load(this);\" value=\"Installer.\" title=\"912\" /><label for=\"eq_9_2\">Installer</label> <br />");
        inputList.Add("<input type=\"radio\" name=\"eq_10\" id=\"eq_9_3\"  onclick=\"nextStepID_load(this);\" value=\"Installer1.\" title=\"913\" /><label for=\"eq_9_3\">InstallerA</label> <br />");
        inputList.Add("<input type=\"radio\" name=\"eq_11\" id=\"eq_9_4\"  onclick=\"nextStepID_load(this);\" value=\"Installer2.\" title=\"914\" /><label for=\"eq_9_4\">InstallerB</label> <br />");
        inputList.Add("<input type=\"radio\" name=\"eq_12\" id=\"eq_9_5\"  onclick=\"nextStepID_load(this);\" value=\"Installer3.\" title=\"915\" /><label for=\"eq_9_5\">InstallerC</label> <br />");
        inputList.Add("<input type=\"radio\" name=\"eq_13\" id=\"eq_9_6\"  onclick=\"nextStepID_load(this);\" value=\"Installer4.\" title=\"916\" /><label for=\"eq_9_6\">InstallerD</label> <br />");

        string output = string.Empty;
        string target = "<button type=\"button\" name=\"{0}\" id=\"{1}\" onclick=\"nextStepID_load('{2}');\">{3}</button><br />";

        foreach (string input in inputList)
        {
            string name = GetValue(@"(?<Value>name=[\S]+)", input);
            string id = GetValue(@"(?<Value>id=[\S]+)", input);
            string title = GetValue(@"(?<Value>title=[\S]+)", input);
            string value = GetValue(@"(?<Value>value=[\S]+)", input);

            output = string.Format(target, name, id, title, value);
            System.Diagnostics.Debug.WriteLine(output);
        }

    }

    private static string GetValue(string pattern, string input)
    {
        Regex regex = new Regex(pattern);
        Match match = regex.Match(input);
        return match.ToString().Split('=').Last().Replace("\"", string.Empty);
    }

这是输入:

    <input type="radio" name="eq_9" id="eq_9_2"  onclick="nextStepID_load(this);" value="Installer." title="912" /><label for="eq_9_2">Installer</label> <br />
    <input type="radio" name="eq_10" id="eq_9_3"  onclick="nextStepID_load(this);" value="Installer1." title="913" /><label for="eq_9_3">InstallerA</label> <br />
    <input type="radio" name="eq_11" id="eq_9_4"  onclick="nextStepID_load(this);" value="Installer2." title="914" /><label for="eq_9_4">InstallerB</label> <br />
    <input type="radio" name="eq_12" id="eq_9_5"  onclick="nextStepID_load(this);" value="Installer3." title="915" /><label for="eq_9_5">InstallerC</label> <br />
    <input type="radio" name="eq_13" id="eq_9_6"  onclick="nextStepID_load(this);" value="Installer4." title="916" /><label for="eq_9_6">InstallerD</label> <br />

这是输出:

    <button type="button" name="eq_9" id="eq_9_2" onclick="nextStepID_load('912');">Installer.</button><br />
    <button type="button" name="eq_10" id="eq_9_3" onclick="nextStepID_load('913');">Installer1.</button><br />
    <button type="button" name="eq_11" id="eq_9_4" onclick="nextStepID_load('914');">Installer2.</button><br />
    <button type="button" name="eq_12" id="eq_9_5" onclick="nextStepID_load('915');">Installer3.</button><br />
    <button type="button" name="eq_13" id="eq_9_6" onclick="nextStepID_load('916');">Installer4.</button><br />

【讨论】:

  • 这是一个非常有趣的方法。 +1。从其他 cmet 中,我几乎认为最好的方法是放下脚并强制改变我们获取数据的方式。或者可能是 HTML 解析。但是这段代码有一些很好的教育,所以再次感谢。
猜你喜欢
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 2014-10-15
  • 2012-03-30
  • 1970-01-01
  • 2019-07-10
相关资源
最近更新 更多