Альтернативные способы сделать условие истинным без использования String Methods [duplicate]

Проверка сообщения «antinome» с использованием двух регулярных выражений: 55 * и 5 *:

REGEX_A: 55 * [Это соответствует «5», «55», «555» и т. д. и делает НЕ соответствует «4», «54» и т. Д.]

REGEX_B: 5 * [Это соответствует «", "5" "55", "555" и т. Д. И не соответствует "4", "54 "и т. д.]

[Здесь мы предположили, что 55 * неявно. 55 . * и 5 * нет. 5 . * - Вот почему 5 * не соответствует 4]

REGEX_A может иметь NFA, как показано ниже:

  {A} - 5 - & gt; {B} -  epsilon - & gt; {C} - 5 - & gt; {D} - epsilon - & gt; {E} {B} ----------------- epsilon -  ------- & GT;  {E} {C} & lt; --- epsilon ------ {E}  

REGEX_B может иметь NFA, как показано ниже:

   {A} - epsilon - & gt; {B} - 5 - & gt; {C} - epsilon - & gt; {D} {A} --------------  epsilon ----------- & gt;  {D} {B} & lt; --- epsilon ------ {D}  

Теперь мы можем получить NFA * DFA (REGEX_A | REGEX_B), как показано ниже:

  NFA: {состояние A} --- epsilon - & gt;  {состояние B} --- 5 - & gt;  {state C} --- 5 - & gt;  {состояние D} {состояние C} --- epsilon - & gt;  {состояние D} {состояние C} & lt; --- epsilon - {состояние D} {состояние A} --- epsilon - & gt;  {state E} --- 5 - & gt;  {состояние F} {состояние E} --- epsilon - & gt;  {состояние F} {состояние E} & lt; --- epsilon - {состояние F} NFA - & gt;  DFA: |  5 |  epsilon * ---- + -------------- + -------- A |  B, C, E, F, G |  A, C, E, F B |  C, D, E, F |  B, C, E, F c |  C, D, E, F |  C D |  C, D, E, F, G |  C, D, E, F E |  C, D, E, F, G |  C, E, F F |  C, E, F, G |  F G |  C, D, E, G |  C, E, F, G 5 (epsilon *) ------------- + --------------------- A |  B, C, E, F, G B, C, E, F, G |  C, D, E, F, G C, D, E, F, G |  C, D, E, F, G Наконец, DFA для (REGEX_A | REGEX_B): {A} - 5 --- & gt; {B, C, E, F, G} - 5 --- & gt;  {C, D, E, F, G} {C, D, E, F, G} --- 5 - & gt;  {C, D, E, F, G} Примечание: {A} является начальным состоянием и {C, D, E, F, G} принимает состояние.   

Аналогично DFA для REGEX_A (55 *):

  |  5 |  epsilon * ---- + -------- + -------- A |  B, C, E |  A B |  C, D, E |  B, C, E C |  C, D, E |  C D |  C, D, E |  C, D, E E |  C, D, E |  C, E 5 (epsilon *) ------- + --------------------- A |  B, C, E B, C, E |  C, D, E C, D, E |  C, D, E {A} ---- 5 ----- & gt;  {B, C, E} - 5 --- {C, D, E} {C, D, E} - 5 --- & gt; {C, D, E} Примечание: {A} является  (C, D, E) принимает состояние  

Аналогично DFA для REGEX_B (5 *):

  |  5 |  epsilon * ---- + -------- + -------- A |  B, C, D |  A, B, D B |  B, C, D |  B C |  B, C, D |  B, C, D D |  B, C, D |  B, D 5 (epsilon *) ------- + --------------------- A |  B, C, D B, C, D |  B, C, D {A} ---- 5 ----- & gt;  {B, C, D} {B, C, D} --- 5 --- & gt;  {B, C, D} Примечание: {A} является начальным состоянием и {B, C, D} принимает состояние  

Выводы:

  DFA  REGX_A | REGX_B, идентичный DFA REGX_A, подразумевает, что REGEX_A является подмножеством REGEX_B DFA REGX_A | REGX_B НЕ идентичен DFA REGX_B - не может выводиться ни о каких gerexes.   
753
задан JJJ 23 December 2013 в 12:58
поделиться

17 ответов

Самый простой способ сделать это (если вас не беспокоят специальные символы Unicode) - вызвать toUpperCase:

var areEqual = string1.toUpperCase() === string2.toUpperCase();
865
ответ дан SLaks 17 August 2018 в 09:45
поделиться

Существует два способа сравнения без учета регистра:

  1. Преобразуйте строки в верхний регистр, а затем сравните их с помощью строгого оператора (===). Как строго оператор обрабатывает операнды, читает материал по адресу: http://www.thesstech.com/javascript/relational-logical-operators
  2. Сравнение шаблонов с использованием строковых методов:

Используйте метод строки поиска для поиска без учета регистра. Читайте о методах поиска и других строковых методах по адресу: http://www.thesstech.com/pattern-matching-using-string-methods

<!doctype html>
  <html>
    <head>
      <script>

        // 1st way

        var a = "apple";
        var b = "APPLE";  
        if (a.toUpperCase() === b.toUpperCase()) {
          alert("equal");
        }

        //2nd way

        var a = " Null and void";
        document.write(a.search(/null/i)); 

      </script>
    </head>
</html>
4
ответ дан A.L 17 August 2018 в 09:45
поделиться

Если обе строки имеют одну и ту же известную локаль, вы можете использовать объект Intl.Collator следующим образом:

function equalIgnoreCase(s1: string, s2: string) {
    return new Intl.Collator("en-US", { sensitivity: "base" }).compare(s1, s2) === 0;
}

Очевидно, что вам может понадобиться кэшировать Collator для повышения эффективности.

Преимущества этого подхода заключаются в том, что он должен быть намного быстрее, чем при использовании RegExps, и основан на чрезвычайно настраиваемом (см. описание параметров конструктора locales и options в статья выше) набор готовых к использованию коллакторов.

1
ответ дан Alexander Abakumov 17 August 2018 в 09:45
поделиться
  • 1
    Другим вариантом для чувствительности является accent, что делает регистр нечувствительным к регистру, но рассматривает a и á как отдельные символы. Таким образом, base или accent могут быть подходящими в зависимости от конкретных потребностей. – Matthew Crumley 13 April 2018 в 16:28

Как насчет того, чтобы НЕ выбрасывать исключения и НЕ использовать медленное регулярное выражение?

return str1 != null && str2 != null 
    && typeof str1 === 'string' && typeof str2 === 'string'
    && str1.toUpperCase() === str2.toUpperCase();

Вышеприведенный фрагмент предполагает, что вы не хотите, чтобы строка была нулевой или неопределенной.

Если вы хотите совместить null / undefined, то:

return (str1 == null && str2 == null)
    || (str1 != null && str2 != null 
        && typeof str1 === 'string' && typeof str2 === 'string'
        && str1.toUpperCase() === str2.toUpperCase());

Если по какой-то причине вам небезразличен неопределенный vs null:

return (str1 === undefined && str2 === undefined)
    || (str1 === null && str2 === null)
    || (str1 != null && str2 != null 
        && typeof str1 === 'string' && typeof str2 === 'string'
        && str1.toUpperCase() === str2.toUpperCase());
1
ответ дан Ben Wilde 17 August 2018 в 09:45
поделиться
  • 1
    Или просто str1 == str2 || ... – SLaks 26 October 2016 в 00:59
  • 2
    @SLaks не уверена, что самое эффективное. Нужно, чтобы кто-то запускал некоторые тесты. Но это также зависит от того, хотите ли вы принимать значения NULL равными, и если вы хотите рассматривать undefined по-разному, и если вы хотите обеспечить тип, чтобы вы не получали исключение для вызова верхнего регистра на число .. Немного сложно. – Ben Wilde 26 October 2016 в 01:06

Предположим, мы хотим найти строковую переменную needle в строковой переменной haystack. Есть три ошибки:

  1. Интернационализированные приложения должны избегать string.toUpperCase и string.toLowerCase. Используйте регулярное выражение, которое вместо этого игнорирует случай. Например, var needleRegExp = new RegExp(needle, "i");, а затем needleRegExp.test(haystack).
  2. Как правило, вы можете не знать значение needle. Будьте осторожны, чтобы needle не содержал никаких регулярных выражений специальных символов . Побегите их с помощью needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
  3. В других случаях, если вы хотите точно сопоставить needle и haystack, просто игнорируя случай, не забудьте добавить "^" в начале и "$" в конце вашего конструктора регулярных выражений.

Принимая во внимание точки (1) и (2), примером может быть:

var haystack = "A. BAIL. Of. Hay.";
var needle = "bail.";
var needleRegExp = new RegExp(needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i");
var result = needleRegExp.test(haystack);
if (result) {
    // Your code here
}
5
ответ дан Chris Chute 17 August 2018 в 09:45
поделиться
  • 1
    Можете ли вы предоставить пример точного соответствия, игнорируя регистр. Вы описываете, как вы это делаете, но если кто-то не знаком с RegExp, может быть неясно, как разместить ^ и $. – HelpMeStackOverflowMyOnlyHope 24 July 2016 в 05:57
  • 2
    Вы делаете ставку! Все, что вам нужно сделать, это заменить часть new RegExp(...) в строке 3 следующим: new RegExp("^" + needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + "$", "i");. Это гарантирует, что нет других символов до или после строки поиска needle. – Chris Chute 26 July 2016 в 21:23

Даже этот вопрос уже ответил. У меня есть другой подход к использованию RegExp и совпадение, чтобы игнорировать регистр. См. Мою ссылку https://jsfiddle.net/marchdave/7v8bd7dq/27/

$("#btnGuess").click(guessWord);

  function guessWord() {

   var letter = $("#guessLetter").val();
   var word = 'ABC';
   var pattern = RegExp(letter, 'gi'); // pattern: /a/gi

   var result = word.match(pattern);
   alert('Ignore case sensitive:' + result);

  }
2
ответ дан David S Lee 17 August 2018 в 09:45
поделиться

С помощью регулярного выражения мы также можем достичь.

(/keyword/i).test(source)

/i для случая игнорирования. Если это не необходимо, мы можем игнорировать и проверять соответствие нечувствительности к регистру, например

(/keyword/).test(source)
24
ответ дан HiDeo 17 August 2018 в 09:45
поделиться
  • 1
    Использование регулярных выражений будет соответствовать подстрокам! В вашем примере строка keyWORD будет указывать результат в положительном совпадении. Но строка this is a keyword yo или keywords также приведет к положительному совпадению. Помните об этом :-) – Elmer 25 October 2017 в 10:25

, если вас беспокоит направление неравенства (возможно, вы хотите отсортировать список), вам очень нужно сделать case-преобразование, а так как в юникоде есть более строчные символы, чем в верхнем регистре toLowerCase, вероятно, лучшее преобразование для использования.

function my_strcasecmp( a, b ) 
{
    if((a+'').toLowerCase() > (b+'').toLowerCase()) return 1  
    if((a+'').toLowerCase() < (b+'').toLowerCase()) return -1
    return 0
}

Javascript, похоже, использует языковой стандарт «C» для сравнения строк, поэтому результирующий порядок будет уродлив, если строки содержат буквы, отличные от ASCII. не так много можно сделать по этому поводу, не делая более подробного осмотра строк.

9
ответ дан Jasen 17 August 2018 в 09:45
поделиться

Как сказано в последних комментариях, string::localCompare поддерживает нечувствительные к регистру сравнения (среди других мощных вещей).

Вот простой пример

'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0

И общую функцию, которую вы могли бы использовать

function equalsIgnoringCase(text, other) {
    text.localeCompare(other, undefined, { sensitivity: 'base' }) === 0;
}

Обратите внимание, что вместо undefined вы, вероятно, должны ввести конкретный язык, с которым работаете. Это важно, как указано в документах MDN

на шведском языке, а а - отдельные базовые буквы

Параметры чувствительности

Поддержка браузера

С момента публикации UC Browser для Android и Opera Mini не поддерживает locale и параметры . Пожалуйста, проверьте https://caniuse.com/#search=localeCompare для актуальной информации.

2
ответ дан Jay 17 August 2018 в 09:45
поделиться

Я написал расширение. очень тривиальный

if (typeof String.prototype.isEqual!= 'function') {
    String.prototype.isEqual = function (str){
        return this.toUpperCase()==str.toUpperCase();
     };
}
0
ответ дан KhanSharp 17 August 2018 в 09:45
поделиться
  • 1
    Что происходит с двумя кодами с разными идеями о том, как String # isEqual должен работать, пытаться существовать одновременно? – Ryan Cavanaugh 20 September 2013 в 23:15
  • 2
    Два не могут существовать одновременно с тем же именем. Если вы добавляете один из них, вы можете либо изменить имя, либо проверить наличие другого. Если другой существует, вы можете использовать другое внутри своей реализации. Если оба из двух разных библиотек, кто бы ни был последним, должен работать сам. Если я могу дать более подробную информацию, я могу иметь глубокий взгляд. (Мне любопытно, почему мой ответ проголосовали?) – KhanSharp 21 September 2013 в 00:22
  • 3
    @KhanSharp Многие считают, что это анти-шаблон, который модифицирует прототип встроенных типов. Вот почему люди могут отказаться от вашего ответа. – jt000 29 July 2014 в 13:45
  • 4
    Разве не считается, что предпочитают неизвестные определения методов? Например, как только какой-либо браузер решает реализовать String#isEqual или Object#isEqual, все ваши страницы ведут себя по-другому и могут делать странные вещи, если спецификация не соответствует вашим требованиям. – Robert 8 December 2014 в 01:07
  • 5
    Я думаю, что у Роберта есть верный момент. Такая отличная идея, но, возможно, соглашение об именах является слишком общим или слишком вероятным для использования в будущем спецификацией JavaScript. Возможно, все ваши методы расширения могут быть prototype.ksxIsEqual, тогда, если вы захотите найти все свои расширения, у вас будет простой способ сделать это, и это, вероятно, никогда не конфликтует. – Eric Bishard 23 August 2015 в 05:35

Здесь много ответов, но я хотел бы добавить решение, основанное на расширении String lib:

String.prototype.equalIgnoreCase = function(str)
{
    return (str != null 
            && typeof str === 'string'
            && this.toUpperCase() === str.toUpperCase());
}

Таким образом вы можете просто использовать его так же, как в Java!

Пример:

var a = "hello";
var b = "HeLLo";
var c = "world";

if (a.equalIgnoreCase(b)) {
    document.write("a == b");
}
if (a.equalIgnoreCase(c)) {
    document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
    document.write("b != c");
}

Выход будет:

"a == b"
"b != c"

String.prototype.equalIgnoreCase = function(str) {
  return (str != null &&
    typeof str === 'string' &&
    this.toUpperCase() === str.toUpperCase());
}


var a = "hello";
var b = "HeLLo";
var c = "world";

if (a.equalIgnoreCase(b)) {
  document.write("a == b");
  document.write("<br>");
}
if (a.equalIgnoreCase(c)) {
  document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
  document.write("b != c");
}

4
ответ дан Nebulosar 17 August 2018 в 09:45
поделиться

Недавно я создал микробиблиотеку, которая предоставляет нечувствительные к регистру строковые помощники: https://github.com/nickuraltsev/ignore-case . (Он внутренне использует toUpperCase.)

var ignoreCase = require('ignore-case');

ignoreCase.equals('FOO', 'Foo'); // => true
ignoreCase.startsWith('foobar', 'FOO'); // => true
ignoreCase.endsWith('foobar', 'BaR'); // => true
ignoreCase.includes('AbCd', 'c'); // => true
ignoreCase.indexOf('AbCd', 'c'); // => 2
8
ответ дан Nick Uraltsev 17 August 2018 в 09:45
поделиться

Поскольку никакой ответ явно не предоставил простой фрагмент кода для использования RegExp, вот моя попытка:

function compareInsensitive(str1, str2){ 
  return typeof str1 === 'string' && 
    typeof str2 === 'string' && 
    new RegExp("^" + str1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "$", "i").test(str2);
}

Он имеет ряд преимуществ:

  1. Проверяет тип параметра (любой нестроковый параметр, например, undefined, например, вырвал бы выражение, подобное str1.toUpperCase()).
  2. Не страдает от возможных проблем интернационализации.
  3. Сбрасывает RegExp.
1
ответ дан Ohad Schneider 17 August 2018 в 09:45
поделиться

используйте regex для сопоставления строк или сравнения,

в javaScript, вы можете использовать match () для сравнения строк, не забудьте поставить i в примере regex

:

var matchString = "Test" ;
if(matchString.match(/test/i) ){
  alert('String matched) ;
}else{
 alert('String not matched') ;
}
2
ответ дан Om Sharma 17 August 2018 в 09:45
поделиться
str = 'Lol', str2 = 'lOl', regex = new RegExp('^' + str + '$', 'i');
if (regex.test(str)) {
    console.log("true");
}
3
ответ дан Parth Raval 17 August 2018 в 09:45
поделиться

EDIT: Этот ответ 7 лет. Сегодня вы должны использовать localeCompare .

Оригинальный ответ

Лучший способ сделать нечувствительное к регистру сравнение в JavaScript - использовать метод RegExp match () с флагом 'i'.

JavaScript: нечувствительный к регистру поиск

Когда обе сравниваемые строки являются переменными (не константами), то это немного сложнее, потому что вам нужно сгенерируйте RegExp из строки, но передача строки в конструктор RegExp может привести к неправильным совпадениям или неудачным совпадениям, если строка содержит специальные символы регулярных выражений.

Если вы интересуетесь интернационализацией, не используйте toLowerCase () или toUpperCase (), поскольку он не обеспечивает точных нечувствительных к регистру сравнений на всех языках.

http://www.i18nguy.com/unicode/turkish-i18n.html

92
ответ дан Samuel Neff 17 August 2018 в 09:45
поделиться
  • 1
    – Sandip Ransing 3 September 2013 в 10:48
  • 2
    Неправильно, это не работает, если строка содержит выражения регулярных выражений. – Stefan Steiger 6 June 2014 в 17:50
  • 3
    @Quandary, да, это то, что я сказал, должно быть обработано - и вам нужно создать RegExp из строки, но передача строки в конструктор RegExp может привести к неправильным совпадениям или неудачным совпадениям, если строка содержит специальные символы регулярных выражений. ; – Samuel Neff 6 June 2014 в 18:29
  • 4
    Использование этого является самым дорогостоящим решением для сравнения строк без учета регистра. RegExp предназначен для сложного сопоставления шаблонов, поэтому он должен построить дерево решений для каждого шаблона, а затем выполнить это против входных строк. Хотя это сработает, это сопоставимо с тем, чтобы взять реактивный самолет, чтобы совершать покупки в следующем блоке. tl; dr: пожалуйста, не делайте этого. – Agoston Horvath 1 April 2015 в 11:30
  • 5
  • 6
    я мог бы использовать localeCompare (), но его возврат -1 для 'a'.localeCompare('A') и, как и op, я ищу сравнение строк, нечувствительное к регистру. – StingyJack 19 March 2018 в 02:53

Помните, что корпус - это специфичная для локали операция. В зависимости от сценария вы можете принять это за счет. Например, если вы сравниваете имена двух человек, вы можете захотеть рассмотреть локаль, но если вы сравниваете машинные сгенерированные значения, такие как UUID, то вы можете этого не сделать. Поэтому я использую следующую функцию в моей утилите utils (обратите внимание, что проверка типа не включена для повышения производительности).

function compareStrings (string1, string2, ignoreCase, useLocale) {
    if (ignoreCase) {
        if (useLocale) {
            string1 = string1.toLocaleLowerCase();
            string2 = string2.toLocaleLowerCase();
        }
        else {
            string1 = string1.toLowerCase();
            string2 = string2.toLowerCase();
        }
    }

    return string1 === string2;
}
24
ответ дан ShitalShah 17 August 2018 в 09:45
поделиться
  • 1
    Есть ли причина, по которой вы используете & quot; !! & quot; для выполнения явного логического преобразования вместо того, чтобы разрешать предложение if для оценки правдоподобия значений? – Celos 28 March 2014 в 15:52
  • 2
    Это не требуется. Думаю, у меня это было из другой версии более сложного кода. Я обновил ответ. – ShitalShah 31 March 2014 в 11:22
  • 3
    Лучше, чем остальные примеры, но все равно выбрасывает ненулевое значение. – Stefan Steiger 6 June 2014 в 17:51
  • 4
    Я предпочитаю эту функцию, спасибо! Просто сделал небольшие изменения, чтобы избежать нулевых проблем. Здесь jsFiddle . – thekodester 25 October 2016 в 18:06
  • 5
    Я рад, что это было полезно. Однако сравнение null == null является спорным. Обычно он должен возвращать ложные данные, но во многих случаях может оказаться желательным вернуть истину. С другой стороны, null == not_null всегда должен возвращать false, которое над кодом делает. – ShitalShah 25 October 2016 в 19:45
Другие вопросы по тегам:

Похожие вопросы: