简体   繁体   English

如何在字符串的反转上使用正则表达式?

[英]How Can I Use a Regex on the Reverse of a string?

I want to use a regex on the reverse of a string . 我想在string的反面使用regex

I can do the following but all my sub_match es are reversed: 我可以执行以下操作,但所有sub_match都是相反的:

string foo("lorem ipsum");
match_results<string::reverse_iterator> sm;

if (regex_match(foo.rbegin(), foo.rend(), sm, regex("(\\w+)\\s+(\\w+)"))) {
    cout << sm[1] << ' ' << sm[2] << endl;
}
else {
    cout << "bad\n";
}

[ Live example ] [ 实例 ]

What I want is to get out: 我想要的是走出去:

ipsum lorem ipsum lorem

Is there any provision for getting the sub-matches that are not reversed? 是否有任何条款可以获得未被撤销的子赛事? That is, any provision beyond reversing the string s after they're matched like this: 也就是说,除了像这样匹配之后将string s反转之外的任何规定:

string first(sm[1]);
string second(sm[2]);

reverse(first.begin(), first.end());
reverse(second.begin(), second.end());

cout << first << ' ' << second << endl;

EDIT: 编辑:

It has been suggested that I update the question to clarify what I want: 有人建议我更新问题以澄清我想要的内容:

Running the regex backwards on the string is not about reversing the order that the matches are found in. The regex is far more complex that would be valuable to post here, but running it backwards saves me from needing a look ahead. string上向后运行regex 并不是要反转找到匹配项的顺序。 regex要复杂得多,这对于在此处发布很有价值,但向后运行它使我无需前瞻。 This question is about the handling of sub-matches obtained from a match_results<string::reverse_iterator> . 这个问题关于从match_results<string::reverse_iterator>获得的子匹配的处理。 I need to be able to get them out as they were in the input, here foo . 我需要能够将它们输出,因为它们在输入中,这里是foo I don't want to have to construct a temporary string and run reverse on it for each sub-match. 我不想构造一个临时string并为每个子匹配运行reverse string How can I avoid doing this. 我怎么能避免这样做。

You could just reverse the order in which you use the results: 您可以反转使用结果的顺序:

#include <regex>
#include <string>
#include <iostream>

using namespace std;

int main()
{
    string foo("lorem ipsum");
    smatch sm;

    if (regex_match(foo, sm, regex("(\\w+)\\s+(\\w+)"))) {
        cout << sm[2] << ' ' << sm[1] << endl; // use second as first
    }
    else {
        cout << "bad\n";
    }
}

Output: 输出:

ipsum lorem

This is absolutely possible! 这绝对是可能的! The key is in the fact that a sub_match inherits from pair<BidirIt, BidirIt> . 关键在于sub_match继承自pair<BidirIt, BidirIt> Since sub_match es will be obtained from: match_results<string::reverse_iterator> sm , the elements of the pair a sub_match inherits from will be string::reverse_iterator s. 由于sub_match es将从: match_results<string::reverse_iterator> sm ,因此sub_match继承的pair的元素将是string::reverse_iterator

So for any given sub_match from sm you can get the forward range from it's second.base() to it's first.base() . 因此,对于来自sm任何给定sub_match ,您可以从它的second.base()到它的first.base()获得前向范围。 You don't have to construct string s to stream ranges but you will need to construct an ostream_iterator : 您不必将string s构造为流范围,但您需要构造一个ostream_iterator

ostream_iterator<char> output(cout);

copy(sm[1].second.base(), sm[1].first.base(), output);
output = ' ';
copy(sm[2].second.base(), sm[2].first.base(), output);

Take heart though, there is a better solution on the horizon! 请记住,有一个更好的解决方案! This answer discusses string_literal s as of right now no action has been taken on them, but they have made it into the "Evolution Subgroup". 这个答案讨论了string_literal 现在没有对它们采取任何行动,但是它们已经进入了“Evolution子组”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM