0

我或多或少有一个这种格式的富文本QString :

<span background-color="red"><a name='item1'></a> property1 </span> + <span background-color="blue"><a name='item2'></a> property2 </span>

它可以有更多标签,但所有标签都将具有相同的结构。此外,在每个标签之间,将显示运算符 - 这是一个应该表示计算的字符串。

我需要一个正则表达式来遍历字符串并提取item1, item2, ...; 还有property1, property2,... 子字符串,这样我就可以检索存储在其他地方的值。

然后,在检索这些之后values,如果,例如, property1=value1 和 property2=value2 ,我需要创建另一个字符串,如:

value1+value2

将评估此字符串以计算计算。

读取字符串的正则表达式是什么?

在复制的字符串中替换的正则表达式是什么?

注意我不打算用这些正则表达式解析HTML 。我需要过滤的富文本字符串最多具有上面表示的标签和结构。它不会有其他类型的标签,也不会有除了上面示例字符串中的属性之外的其他属性。它只能有更多相同标签结构的示例:一个跨度,包含一个带有名称属性的锚标签和一些要显示的文本。

NOTE2 @Passerby 在这个问题的评论中发布了一个非常近似的解决方案的链接。我忘记了关于我的目标的一个(希望很小的)细节:我还需要将span标签之间的任何内容都捕获为字符串,而不是简单地检查char类似@Passerby(非常好)建议的内容。有任何想法吗?

NOTE3我实际上仍然认为这与重复标记的问题不是同一个问题。虽然我过滤的字符串看起来像 HTML,但它们实际上是富文本。它们将始终具有这种严格的结构/格式,因此 RegEx 对于我需要做的事情是完全可行的。在我从一些用户那里得到了一些很棒的评论之后,即@Passerby,我决定去做,这非常适合我的需要:

示例字符串:

<span background-color="red"><a name='item1'></a> property1 </span> + 300 * <span background-color="blue"><a name='item2'></a> property2 </span> + Math.sqrt(<span background-color="green"><a name='item3'></a> property3 </span>)

正则表达式:

/ <span.*?><a name='(.*?)'><\/a>\s*(.*?)\s*<\/span>(((.*?)?)(?=<)|) / g

输出:

MATCH 1 
1. [38-43] `item1` 
2. [50-59] `property1` 
3. [67-76] ` + 300 * ` 
4. [67-76] ` + 300 * ` 
5. [67-76] ` + 300 * ` 
MATCH 2 
1. [115-120] `item2` 
2. [127-136] `property2` 
3. [144-157] ` + Math.sqrt(` 
4. [144-157] ` + Math.sqrt(` 
5. [144-157] ` + Math.sqrt(` 
MATCH 3 
1. [197-202] `item3` 
2. [209-218] `property3` 
3. [226-226] (null, matches any position) 
4

2 回答 2

1

这可能是这样的:

QRegExp rx("^(?:\\<span background-color=\"red\"\\>\\<a name=')(\\w)(?:'\\>\\</a\\>)\s*(\\d+)\s*(?:\\</span\\>)\s*(\+)\s*(?:\\<span background-color=\"blue\"\\>\\<a name=')(\\w)(?'\\>\\</a\\>)\")\\s*(\\d+)\\s*\\</span\\>)$");

rx.IndexIn(myText);
qDebug() << rx.cap(1) << rx.cap(2) << rx.cap(3) << rx.cap(4) << rx.cap(5);
//will return item1 prop1 + item2 prop2

givenitem将是一个单词,并且property将是一个数字。我在我们的软件的计算器中做了非常相似的事情。

诀窍是,从小部分开始:

rx("\\<a name='\\w'\\>");

这将捕获项目,但最终会捕获完整的行。然后继续下一点并保持它,直到你得到你想要的整条线。正则表达式可能非常强大,但也非常令人沮丧。

祝你好运

编辑:每个括号 () 都可以通过替换函数中的 \1 访问。(?:) 括号没有被捕获!所以 :

QString text = "My Text";
text.replace("^My( Text)$","His\\1");
//will have returned: His Text
于 2013-07-10T11:35:11.517 回答
0

我也不懂正则表达式。对于这种解析问题,我会使用这样的快速和(也许)肮脏的解决方案:

QString str = "<span background-color='red'><a name='item1'></a> property1 </span> + <span background-color='blue'><a name='item2'></a> property2 </span>";
QStringList slist = str.split("<");

qDebug() << slist;

foreach (QString s, slist)
{
    if (s.startsWith("/a"))
    {
        qDebug() << "property:" << s.split(" ")[1];
    }
    else if (s.startsWith("a name"))
    {
        qDebug() << "item:" << s.split("'")[1];
    }
    else if (s.startsWith("/span>"))
    {
        QString op = s.mid(6).trimmed();
        if (op != "")
            qDebug() << "operator:" << op;
    }
}

输出是:

item: "item1" 
property: "property1" 
operator: "+" 
item: "item2" 
property: "property2"

当然,如果格式发生变化,这将崩溃。但是正则表达式也是如此。

如果格式更复杂,我会尝试将格式更改为有效的 XML,然后使用 Qt 的 XML 类来解析数据。

如果您最终使用这种解决方案,我真的建议您添加一些额外的有效性检查。

于 2013-07-10T10:42:18.910 回答