2017-01-28 3 views
2

У меня есть программаString.Replace не работает, как ожидалось

public void TestMethod2() 
    { 
     string[] keywords = 
     { 
      "SELECT", "FROM", "WHERE", "GROUP", "HAVING", "ORDER", "LEFT", "RIGHT", "JOIN", "INNER", "OUTER", "ASC", 
      "DESC", "AND", "OR","IN", "BETWEEN", "BY", "NOT", "ON", "AS", "CASE", "WHEN", "ELSE", "UPDATE", "SET" 
     }; 

     var actualString = "SELECT * FROm A Join B On C in D case e join t left outer join inner join right join"; 

     foreach (var text in actualString.Split(' ')) 
     { 
      var isExists = keywords.Any(x => x.Equals(text, StringComparison.OrdinalIgnoreCase)); 

      if (!isExists) 
      { 
       continue; 
      } 

      actualString = actualString.Replace(text, text.ToUpper()); 
     } 


     var expectedString = "SELECT * FROM A JOIN B ON C IN D CASE e JOIN t LEFT OUTER JOIN INNER JOIN RIGHT JOIN"; 

    } 

Я новичок в C#. Я не понимаю, почему метод Replace() не работает должным образом. Он показывает выход SELECT * FROM A JOIN B ON C IN D СЛУЧАЙ е РЕГИСТРИРУЙТЕСЬ т LEFT OUTER JOIN INNER JOIN RIGHT JOIN

Может кто-то пожалуйста просветить меня почему Replace() ведет себя, как это? Спасибо заранее.

ответ

2

Он ведет себя так, как ожидалось. Вот вывод построчно:

 
[SELECT] -> SELECT * FROm A Join B On C in D case e join t left outer join inner join right join 
[FROm] -> SELECT * FROM A Join B On C in D case e join t left outer join inner join right join 
[Join] -> SELECT * FROM A JOIN B On C in D case e join t left outer join inner join right join 
[On]  -> SELECT * FROM A JOIN B ON C in D case e join t left outer join inner join right join 
[in]  -> SELECT * FROM A JOIN B ON C IN D case e joIN t left outer joIN INner joIN right joIN 
[case] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t left outer joIN INner joIN right joIN 
[join] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t left outer joIN INner joIN right joIN 
[left] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t LEFT outer joIN INner joIN right joIN 
[outer] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t LEFT OUTER joIN INner joIN right joIN 
[join] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t LEFT OUTER joIN INner joIN right joIN 
[inner] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t LEFT OUTER joIN INner joIN right joIN 
[join] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t LEFT OUTER joIN INner joIN right joIN 
[right] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t LEFT OUTER joIN INner joIN RIGHT joIN 
[join] -> SELECT * FROM A JOIN B ON C IN D CASE e joIN t LEFT OUTER joIN INner joIN RIGHT joIN 

Вы можете видеть, что, когда в заменяется на В, в строке 5; затем присоединиться к заменяется на РЕГИСТРИРУЙТЕСЬ

Но тогда, что случилось, что ваш призыв к Keywords.Any работает правильно, и соответствует присоединиться и РЕГИСТРИРУЙТЕСЬ, однако, заменить вызов все еще чувствительный к регистру, и замена не состоится.

Replace is C# чувствителен к регистру и, к сожалению, .NET не предлагает версию, не учитывающую регистр; но есть решения, плавающие вокруг.

Проверить this link для замены нечувствительного к регистру.

+0

Спасибо @Thomas. Понял. –

8

Если вы отлаживаете его, вы заметите, что ваше ключевое слово «в» заменяет второе соединение, поэтому вы получаете joIN. Позже ваша текстовая переменная попытается заменить «join» на «JOIN», но не найдет «join», потому что часть ее была в верхнем регистре.

+1

Поскольку речь идет о SQL-строка, и те, не может начинаться или заканчиваться «в» или другой SQL слово дроби, простое исправление окружать как иглы и стог сена с пробелами. Также: обратите внимание на первые три слова ответа! – TaW

+0

@Zbigniew - Вообще-то моя ошибка была в том, что я думал, что foreach работает как цикл. Теперь я понял. Благодарю. –

+0

@NoorAShuvo Я не вижу, как это поможет. – MistyK

0

Проблема в том, что вы уже замените IN в соединении. Поэтому сравнение не выполняется, если вы хотите заменить соединение с помощью JOIN. (joIN! = join)

+0

Это уже ответили 10 минут назад – MistyK

+2

Я набираю номер на своем мобильном телефоне, так что мне потребовалось некоторое время ... –

0

Есть четкое представление из ответов here.Finally решить, что, изменяя Еогеасп с для цикла. Спасибо вам всем.

public void TestMethod2() 
{ 
    string[] keywords = 
    { 
     "SELECT", "FROM", "WHERE", "GROUP", "HAVING", "ORDER", "LEFT", "RIGHT", "JOIN", "INNER", "OUTER", "ASC", 
     "DESC", "AND", "OR","IN", "BETWEEN", "BY", "NOT", "ON", "AS", "CASE", "WHEN", "ELSE", "UPDATE", "SET" 
    }; 

    var actualString = "SELECT * FROm A Join B On C in D case e join t left outer join inner join right join"; 

    var cnt = sqlTest.Split(' ').Count(); 
    for (int i = 0; i < cnt; i++) 
    { 
     var text = sqlTest.Split(' ')[i]; 
     var isExists = keywords.Any(x => x.Equals(text, StringComparison.OrdinalIgnoreCase)); 

     if (!isExists) 
     { 
      continue; 
     } 

     actualString = actualString.Replace(text, text.ToUpper()); 
    } 


    var expectedString = "SELECT * FROM A JOIN B ON C IN D CASE e JOIN t LEFT OUTER JOIN INNER JOIN RIGHT JOIN"; 

} 
0

Я предлагаю использовать Regex.Replace вместо того, чтобы просто String.Replace с

\bKeyWord\b 

узора с целью лечения подстроки в качестве ключевого слова, если и только если это целого слова:

select horror 
    from torro 
    where corner = 1 
    or ordain = 2 

следует преобразовать в

SELECT horror -- even if horror has two "or" 
    FROM torro -- even if torro has two "or" 
    WHERE corner = 1 -- even if corner contains "or" 
    OR ordain = 2 -- even if ordain contains "or" 

Реализация:

string[] keywords = { 
    "SELECT", "FROM", "WHERE", "GROUP", "HAVING", "ORDER", "LEFT", "RIGHT", 
    "JOIN", "INNER", "OUTER", "ASC", "DESC", "AND", "OR","IN", "BETWEEN", 
    "BY", "NOT", "ON", "AS", "CASE", "WHEN", "ELSE", "UPDATE", "SET" 
}; 

var actualString = 
    "SELECT * FROm A Join B On C in D case e join t left outer join inner join right join"; 

foreach (var keyword in keywords) 
    actualString = Regex.Replace(
    actualString, 
    @"\b" + Regex.Escape(keyword) + @"\b", 
    keyword.ToUpper(), 
    RegexOptions.IgnoreCase); 
Смежные вопросы