2015-03-31 63 views
0

Perl有e正則表達式修飾符,它允許使用Perl代碼而不僅僅是一個字符串來制定替換:http://perldoc.perl.org/perlretut.html#Search-and-replace儘管這個例子並不是最好的,因爲有交換機來完成這個工作。對於那些你們誰瞭解Perl的下面是一個更有意義的例子:是否有支持內聯代碼的regex_replace變體?

$string = "StackOverflow user: Jonathan Mee"; 

$string =~ s/:\s*(.*)$/$1 == "Jonathan Mee" ? ": ".$1." is AWESOME!" : ": ".$1." is ???"/e; 

print $string; #Will print "StackOverflow user: Jonathan Mee is AWESOME!" 

有++中regex_replace變種用C,讓我做同樣的事情?如代碼內聯代替。

回答

0

regex_replace有6種不同的過載。 fmt參數對於它們中的每一個都使用相同的方式:

用於替換每個匹配的字符串。 這可能包括格式說明符和轉義序列,這些格式說明符和轉義序列被它們所代表的字符替換。

每個6個重載的體育運動也被用於控制,一個flags參數「fmt是如何被格式化」。該fmt相關的選項有:

  • format_default:默認格式
    使用標準格式規則取代匹配(即由ECMAScript中的使用替代方法)。
  • format_sed sed格式化
    使用與POSIX中的sed實用程序相同的規則來替換匹配項。
  • format_no_copy無副本
    替換匹配時,不會複製目標序列中與正則表達式不匹配的部分。
  • format_first_only僅限第一個
    只替換第一次出現的正則表達式。

請注意,沒有fmt重載,也沒有flags支持內聯代碼。所以答案是:不,沒有支持嵌入代碼的regex_replace的變種。


但是,如果你願意配合使用STD算法regex_iterator,你可以使用lambda來實現在線代碼。

const string foo("StackOverflow user: Jonathan Mee"); 
vector<string> bar; 

transform(regex_iterator<string::const_iterator>(foo.cbegin(), foo.cend(), regex(".*:\\s*(.*)")), 
      regex_iterator<string::const_iterator>(), 
      back_inserter(bar), 
      [](const smatch& i){auto result = i.str(); 

           if (!result.empty()){ 
            result += (i.str(1) == "Jonathan Mee" ? " is AWESOME!" : " is ???"); 
           } 
           return result;}); 

正如你可以看到拉姆達是在transform採取在當前regex_iteratorsmatch使用。這是非常可擴展到多行字符串,在string foo("StackOverflow user: Jonathan Mee\nStackOverflow user: user0");示例中的輸出是:

StackOverflow的用戶:喬納森眉是真棒!
StackOverflow用戶:user0是???

很明顯,有一些折衷與smatchregex_replace工作。其中str(1)屬於str()未指定。在這裏,我利用了foo末尾的事實,而不是foo中間的某處。但應該指出的是,Perl的e修飾符也遇到了同樣的困難,所以我認爲這幾乎是平等的。

相關問題