【问题标题】:Extract persian and english characters between HTML tags提取 HTML 标签之间的波斯文和英文字符
【发布时间】:2019-03-31 00:57:56
【问题描述】:

有人能帮我为这个 HTML 标签制作 regx 吗?

<h1 class="c-product__title">
    هندزفری بلوتوث مدل HBQ-I7
                <span>HBQ-I7 Bluetooth Handsfree</span></h1>

我要提取 "هندزفری بلوتوث مدل HBQ-I7""HBQ-I7蓝牙免提"
谢谢

【问题讨论】:

  • 你真的需要使用正则表达式吗?您是否考虑过使用 HTML Agility Pack 或 Linq to XML?
  • &lt;h1 class="c-product__title"&gt;&lt;span&gt; 会改变吗?

标签: c# html regex tags


【解决方案1】:
var source = @"<h1 class=""c-product__title"">هندزفری بلوتوث مدل HBQ-I7<span>HBQ-I7 Bluetooth Handsfree</span></h1>";
var regex = new Regex(@"product__title"">(?<farci>.+)<span>(?<english>.+)</span>");
var match = regex.Match(source);

这将返回 3 个组,第一个匹配整个正则表达式,然后再返回 2 个,一个用波斯语称为 farci,第二个用英语版本称为英语。

只有当它们都在同一行时才有效。如果你有换行符,那么它将不起作用。

如果您可以将 html 视为 xml 并使用 Linq 可能更容易,那么换行符不是问题。

【讨论】:

  • 鉴于 OP 的示例 HTML,我会假设元素之间会有一些空格(包括换行符等)。
【解决方案2】:

使用正则表达式

string html = @"<h1 class=""c-product__title"">
    هندزفری بلوتوث مدل HBQ-I7
                <span>HBQ-I7 Bluetooth Handsfree</span></h1>";

string h1Start = @"<h1.*?>"; // h1 tag, with or without attributes
string spanStart = @"<span.*?>"; // span tag, with or without attributes
string spanEnd = @"</span>"; // span closing tag
string text = @"\s*(.+)\s*"; // there MIGHT be whitespace before and/or after the text
var regex = new Regex($"{h1Start}{text}{spanStart}{text}{spanEnd}");

Match match = regex.Match(html);

if (match.Success)
{
    string persianText = match.Groups[1].Value.Trim();
    string englishText = match.Groups[2].Value.Trim();
}

替代解决方案 - 使用 HtmlAgilityPack

认为在这种特殊情况下,HtmlAgilityPack 是比正则表达式更好的选择来解析 HTML 片段。

例子:

using System;
using System.Linq;
using HtmlAgilityPack;

namespace HtmlAgilityPackDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string html = @"<h1 class=""c-product__title"">
    هندزفری بلوتوث مدل HBQ-I7
                <span>HBQ-I7 Bluetooth Handsfree</span></h1>";

            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(html);

            var text = (from node in doc.DocumentNode.ChildNodes
                let textNode = node.SelectSingleNode("//text()") // selects the text 
                let spanNode = node.SelectSingleNode("span")
                select new 
                {
                    PersianText = textNode.InnerText.Trim(),
                    EnglishText = spanNode.InnerText.Trim()
                })
                .FirstOrDefault();

            Console.Read();
        }
    }
}

【讨论】:

    【解决方案3】:

    如果您在 C# 代码中将 HTMLTag 作为字符串,您可以尝试使用 .split() 方法来提取您想要/需要的部分。例如:

    String htmlTag = " < h1 class=\"c-product__title\">    هندزفری بلوتوث مدل HBQ-I7                <span> HBQ-I7 Bluetooth Handsfree</span></h1>";
    string[] htmlTagSplitted = htmlTag.Split('<');
    string[] htmlTagSplitted2 = new string[20];
    string[] htmlTagSplitted3 = new string[20];          
    htmlTagSplitted2 = htmlTagSplitted[1].Split('>');
    htmlTagSplitted3 = htmlTagSplitted[2].Split('>');
    
    Console.WriteLine(htmlTagSplitted2[1] + htmlTagSplitted3[1]);
    

    htmlTagSplitted2[1] 包含您想要的字符串的第一部分,而 htmlTagSplitted3[1] 第二部分。我知道这不是正则表达式,也不是漂亮的语法,但它确实有效:-D

    最好的问候尼科!

    【讨论】:

    • 哇,看看其他答案,我很后悔我的帖子:facepalm:尽管如此它仍然有效^^
    • 这样解析字符串更容易出错,以防输入 html 发生变化(换行符、间距等)。您的代码也不太可读 IMO... 有时困难的部分是为正确的工作找到正确的工具!但是,嘿,尝试使用 String.Split 来做这件事仍然是一个很好的练习;-)
    • 感谢您的支持反馈! :-) 到目前为止,我在编写的程序中使用了 String.Split 几次,所以我认为它可能适合呵呵。我希望将来我能够使用更多改进的解决方案,例如您向 OP 建议的解决方案,呵呵! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多