我在这种格式中或多或少地拥有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 。我需要过滤的富文本字符串最多 上面标记的代码和结构。除了上面示例字符串中的标记之外,它不会有其他类型的标记,也不会有其他属性。它只能包含 more 相同标记结构的示例:span,包含带有 name 属性的锚标记和一些要显示的文本。
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)
答案 0 :(得分: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
给定item
将是一个单词,property
将是一个数字。我在软件计算器中做了类似的事情。
诀窍是,从小位开始:
rx("\\<a name='\\w'\\>");
将捕获该项目,但最终捕获完整的行。然后继续下一步并继续它,直到你得到你想要它的整行。 正则表达式可能非常强大但也非常令人沮丧。
祝你好运编辑:可以通过替换功能中的\ 1访问每个括号()。 (?:)括号未被捕获!所以:
QString text = "My Text";
text.replace("^My( Text)$","His\\1");
//will have returned: His Text
答案 1 :(得分: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类来解析数据。
如果你最终使用这种解决方案,我真的建议添加一些额外的有效性检查。