正则表达式有时简单而复杂。坚持要替换具有变量的表达式,假设变量具有以下模式:
#include<iostream>
#include<string.h>
using namespace std;
int main()
{ char word1[50], word2[50];
unsigned int code = 0, i, j, counter = 0, ok = 1;
cout << "Type in the first word and then press ENTER:";
cin.getline(word1, 50);
cout << "Type in the second word and then press ENTER:";
cin.getline(word2, 50);
cout << endl;
if (strlen(word1) == strlen(word2)) //If the two words don't have the same lenght, it's impossible to obtain one word of the other by permutating it's letters.
{ for (i = 0; word1[i]; i++) /*This nested FOR will generate a number in the code variable. The first digit will indicate how many times will the letter word1[0] be found in word2,
the second digit will indicate how many times will the letter word1[1] be found in word2 and so on until the end of word1*/
{ counter = 0;
for (j = 0; word2[j]; j++)
if (word1[i] == word2[j])
counter += 1;
code = code * 10 + counter;
}
i = strlen(word1) - 1;
while (i >= 0 && ok) /*In this loop we are checking if the code is valable also for the word1 itself. If it is, it means that the words can be obtained one of the other by permutating the letters*/
{ counter = 0;
for (j = strlen(word1) - 1; j >= 0; j--)
if (word1[i] == word1[j])
counter++;
if (counter == code % 10)
ok = 1;
else
ok = 0;
code = code / 10;
i--;
}
if (ok)
cout << "Yes, the words can be obtained one of the other by permutating the letters.";
else
cout << "No, the words can not be obtained one of the other by permutating the letters.";
}
else
cout << "No, the words can not be obtained one of the other by permutating the letters.";
cin.get();
}
我想替换我的变量替换点(。)的所有出现,因为我必须最终标记表达式,其中tokenizer不识别具有点的变量。所以我想在解析之前用下划线替换它们。在标记化之后,我想获得具有原始值的变量标记。
表达式:
\w+(\.\w+)*
三个变量:
(x1.y2.z3 + 9.99) + y2_z1 - x1.y2.z3
期望的输出:
x1.y2.z3
y2_z1
x1.y2.z3
问题1:在这种情况下如何使用Regex替换?
问题2:有没有更好的方法来解决上述问题,因为变量可以有下划线,所以用下划线替换dot不是将原始变量放回令牌的可行解决方案?
答案 0 :(得分:1)
这种正则表达式似乎有效:[a-zA-Z]+\d+\S+
要替换匹配中仅找到 的点,请使用MatchEvaluator:
private static char charToReplaceWith = '_';
static void Main(string[] args)
{
string s = "(x1.y2.z3 + 9.99) + y2_z1 - x1.y2.z3";
Console.WriteLine(Regex.Replace(s, @"[a-zA-Z]+\d+\S+", new MatchEvaluator(ReplaceDotWithCharInMatch)));
Console.Read();
}
private static string ReplaceDotWithCharInMatch(Match m)
{
return m.Value.Replace('.', charToReplaceWith);
}
这给出了这个输出:
(x1_y2_z3 + 9.99) + y2_z1 - x1_y2_z3
我不完全理解你的第二个问题,以及如何处理已经有下划线的标记化变量,但你应该能够选择要替换的字符(即if (string.Contains('_'))
是{{1然后你选择一个不同的字符替换,但可能必须维护一个字典,上面写着&#34;我用下划线替换了所有的点,用true
替换所有下划线等。)。
答案 1 :(得分:0)
试试这个:
string input = "(x1.y2.z3 + 9.99) + y2_z1 - x1.y2.z3";
string output = Regex.Replace(input, "\\.(?<![a-z])", "_");
这将仅替换后跟字母(a-z)的句点。
答案 2 :(得分:0)
通过制作以(?!
点后跟非数字的东西就像这样简单:
// matches any dot NOT followed by a character in the range 0-9
String output = Regex.Replace(input, "\\.(?![0-9])", "_");
这样做的好处是虽然[0-9]是表达式的一部分,但它只被检查为在后面的匹配,但实际上并不是匹配的一部分。