你能转换成C++;std::regex表达式到C#表达式?
我用正则表达式对查找匹配的内容进行C#编码,并用你能转换成C++;std::regex表达式到C#表达式?,c#,c++,regex,c++-cli,C#,C++,Regex,C++ Cli,我用正则表达式对查找匹配的内容进行C#编码,并用I#替换它。但是看起来C++表达式和C语言的工作方式不一样。请将其转换或提供一些提示 我在Visual Studio Express 2012工作。看起来C#regex也需要\ 表达方式: //letter + possible letters or numbers without numbers before first letter "(?:^|[^\\d])\\b([a-zA-Z][a-zA-Z\\d]*)" //exponenci
I#
替换它。但是看起来C++表达式和C语言的工作方式不一样。请将其转换或提供一些提示
我在Visual Studio Express 2012工作。看起来C#regex也需要\
表达方式:
//letter + possible letters or numbers without numbers before first letter
"(?:^|[^\\d])\\b([a-zA-Z][a-zA-Z\\d]*)"
//exponencial number like 1.10E+5
"\\d(\\.?\\d+)?E[+-]\\d+"
//next two is pretty obvious
"\\d+\\.\\d+"
"\\d+"
C#代码:
string input=“FGS1=(B+A*(5.01E+10))+A*10+(C*10.5)*51E-10+5.01E+10”;
正则表达式r=新正则表达式(rExp);
var标识符=新字典();
MatchEvaluator me=委托(匹配m)
{
控制台写入线(m);
var variableName=m.ToString();
if(标识符.ContainsKey(变量名称))
{
返回标识符[variableName];
}
其他的
{
i++;
var newVariableName=“i”+i.ToString();
标识符[variableName]=新的variableName;
返回newVariableName;
}
};
输入=r.替换(输入,me);
是和否。您不必将正则表达式从std::regex
转换为C
。您只需告诉C#
使用不同的行为即可。以下是原因和方法:
在C#
中:
默认情况下,正则表达式引擎在将正则表达式模式与输入文本匹配时使用规范行为
相反,std::regex
:
默认情况下,此库中的函数使用ECMAScript语法
要使std::regex
表达式在C#
中工作,需要使用并设置ECMAScript
选项:
new Regex(pattern, RegexOptions.ECMAScript | RegexOptions.IgnoreCase);
为表达式启用符合ECMAScript的行为。此值只能与IgnoreCase、多行和编译值一起使用。将此值与任何其他值一起使用会导致异常
ECMAScript和规范正则表达式的行为不同
在三个方面:
- 字符类在匹配表达式中的指定方式不同。默认情况下,规范正则表达式支持Unicode字符类别。ECMAScript不支持Unicode
- 具有自身反向引用的正则表达式捕获类必须在每次捕获迭代中更新李>
- 八进制转义和反向引用之间的歧义处理方式不同
var input = "123";
var pattern = "\\d";
var result1 = Regex.Replace(input, pattern, "_", RegexOptions.ECMAScript); // produces "___"
var result2 = RegexTest.Replace(input, pattern, "_"); // produces "___"
String^ RegexTest::Replace(String^ input, String^ pattern, String^ replacement) {
using namespace Runtime::InteropServices;
const char* p_input = (const char*)(Marshal::StringToHGlobalAnsi(input)).ToPointer();
const char* p_pattern = (const char*)(Marshal::StringToHGlobalAnsi(pattern)).ToPointer();
const char* p_replacement = (const char*)(Marshal::StringToHGlobalAnsi(replacement)).ToPointer();
try {
std::string _input(p_input);
std::string _replacement(p_replacement);
std::regex re = std::regex(p_pattern);
std::string result = std::regex_replace(_input, re, _replacement);
return gcnew String(result.c_str());
} finally {
Marshal::FreeHGlobal(IntPtr((void*)p_pattern));
Marshal::FreeHGlobal(IntPtr((void*)p_input));
Marshal::FreeHGlobal(IntPtr((void*)p_replacement));
}
}
在一些评论中,建议使用C#
中的逐字字符串(而不是全部转义)。事实上,这是行不通的,因为:
正则表达式处理(带有STD:ReGEX)在C++中并不方便,因为它在Perl语言中有内置正则表达式支持。一个原因是逃逸序列。要将反斜杠\发送到正则表达式引擎,必须在源代码中键入\。例如,考虑这些定义。
因此OP定义的模式是正确的例如:
C#
:
var input = "123";
var pattern = "\\d";
var result1 = Regex.Replace(input, pattern, "_", RegexOptions.ECMAScript); // produces "___"
var result2 = RegexTest.Replace(input, pattern, "_"); // produces "___"
String^ RegexTest::Replace(String^ input, String^ pattern, String^ replacement) {
using namespace Runtime::InteropServices;
const char* p_input = (const char*)(Marshal::StringToHGlobalAnsi(input)).ToPointer();
const char* p_pattern = (const char*)(Marshal::StringToHGlobalAnsi(pattern)).ToPointer();
const char* p_replacement = (const char*)(Marshal::StringToHGlobalAnsi(replacement)).ToPointer();
try {
std::string _input(p_input);
std::string _replacement(p_replacement);
std::regex re = std::regex(p_pattern);
std::string result = std::regex_replace(_input, re, _replacement);
return gcnew String(result.c_str());
} finally {
Marshal::FreeHGlobal(IntPtr((void*)p_pattern));
Marshal::FreeHGlobal(IntPtr((void*)p_input));
Marshal::FreeHGlobal(IntPtr((void*)p_replacement));
}
}
C++/CLI
:
var input = "123";
var pattern = "\\d";
var result1 = Regex.Replace(input, pattern, "_", RegexOptions.ECMAScript); // produces "___"
var result2 = RegexTest.Replace(input, pattern, "_"); // produces "___"
String^ RegexTest::Replace(String^ input, String^ pattern, String^ replacement) {
using namespace Runtime::InteropServices;
const char* p_input = (const char*)(Marshal::StringToHGlobalAnsi(input)).ToPointer();
const char* p_pattern = (const char*)(Marshal::StringToHGlobalAnsi(pattern)).ToPointer();
const char* p_replacement = (const char*)(Marshal::StringToHGlobalAnsi(replacement)).ToPointer();
try {
std::string _input(p_input);
std::string _replacement(p_replacement);
std::regex re = std::regex(p_pattern);
std::string result = std::regex_replace(_input, re, _replacement);
return gcnew String(result.c_str());
} finally {
Marshal::FreeHGlobal(IntPtr((void*)p_pattern));
Marshal::FreeHGlobal(IntPtr((void*)p_input));
Marshal::FreeHGlobal(IntPtr((void*)p_replacement));
}
}
使用逐字字符串文字,而不是转义所有内容。@SLaks您可能指的是@πάνταῥεῖ: 不我的意思是C字形字符串,你的C++版本看起来像什么,你有什么问题?