String comparison: Difference between revisions

Add Ecstasy example
(FutureBasic solution added)
(Add Ecstasy example)
 
(15 intermediate revisions by 11 users not shown)
Line 1,108:
{{out}}
<pre>Igual que la entrada de FreeBASIC.</pre>
 
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic">REM >strcomp
shav$ = "Shaw, George Bernard"
shakes$ = "Shakespeare, William"
:
REM test equality
IF shav$ = shakes$ THEN PRINT "The two strings are equal" ELSE PRINT "The two strings are not equal"
:
REM test inequality
IF shav$ <> shakes$ THEN PRINT "The two strings are unequal" ELSE PRINT "The two strings are not unequal"
:
REM test lexical ordering
IF shav$ > shakes$ THEN PRINT shav$; " is lexically higher than "; shakes$ ELSE PRINT shav$; " is not lexically higher than "; shakes$
IF shav$ < shakes$ THEN PRINT shav$; " is lexically lower than "; shakes$ ELSE PRINT shav$; " is not lexically lower than "; shakes$
REM the >= and <= operators can also be used, & behave as expected
:
REM string comparison is case-sensitive by default, and BBC BASIC
REM does not provide built-in functions to convert to all upper
REM or all lower case; but it is easy enough to define one
:
IF FN_upper(shav$) = FN_upper(shakes$) THEN PRINT "The two strings are equal (disregarding case)" ELSE PRINT "The two strings are not equal (even disregarding case)"
END
:
DEF FN_upper(s$)
LOCAL i%, ns$
ns$ = ""
FOR i% = 1 TO LEN s$
IF ASC(MID$(s$, i%, 1)) >= ASC "a" AND ASC(MID$(s$, i%, 1)) <= ASC "z" THEN ns$ += CHR$(ASC(MID$(s$, i%, 1)) - &20) ELSE ns$ += MID$(s$, i%, 1)
NEXT
= ns$</syntaxhighlight>
{{out}}
<pre>The two strings are not equal
The two strings are unequal
Shaw, George Bernard is lexically higher than Shakespeare, William
Shaw, George Bernard is not lexically lower than Shakespeare, William
The two strings are not equal (even disregarding case)</pre>
 
==={{header|QBasic}}===
Line 1,218 ⟶ 1,255:
<pre>Igual que la entrada de FreeBASIC.</pre>
==={{header|uBasic/4tH}}===
{{works with|R3R4}}
uBasic/4tH provides a builtin, case insensitive function to compare two strings, called <code>COMP()</code> which returns either a negative, zero or positive value, just like <code>strcmp()</code>. In order to compare two strings case sensitive, a user defined function is required.
<syntaxhighlight lang="text">Print "Case sensitive"
Print "=============="
Print Show (FUNC(_Eval(FUNC(_StrCmp (Dup ("Dog"), Dup ("Dog"))))))
Print Show (FUNC(_Eval(FUNC(_StrCmp (Dup ("Dog"), Dup ("Cat"))))))
Print Show (FUNC(_Eval(FUNC(_StrCmp (Dup ("Dog"), Dup ("Rat"))))))
Print Show (FUNC(_Eval(FUNC(_StrCmp (Dup ("Dog"), Dup ("dog"))))))
Print Show (FUNC(_Eval(FUNC(_StrCmp (Dup ("Dog"), Dup ("Pig"))))))
 
Print
Line 1,254 ⟶ 1,291:
_Eval ' evaluate result
Param (1)
If a@ = 0 Then Return (Dup ("Equal"))
If a@ > 0 Then Return (Dup ("Second before First"))
Return (Dup ("First before Second"))</syntaxhighlight>
Output:
<pre>
Line 1,277 ⟶ 1,314:
0 OK, 0:673
</pre>
 
=={{header|BBC BASIC}}==
<syntaxhighlight lang="bbcbasic">REM >strcomp
shav$ = "Shaw, George Bernard"
shakes$ = "Shakespeare, William"
:
REM test equality
IF shav$ = shakes$ THEN PRINT "The two strings are equal" ELSE PRINT "The two strings are not equal"
:
REM test inequality
IF shav$ <> shakes$ THEN PRINT "The two strings are unequal" ELSE PRINT "The two strings are not unequal"
:
REM test lexical ordering
IF shav$ > shakes$ THEN PRINT shav$; " is lexically higher than "; shakes$ ELSE PRINT shav$; " is not lexically higher than "; shakes$
IF shav$ < shakes$ THEN PRINT shav$; " is lexically lower than "; shakes$ ELSE PRINT shav$; " is not lexically lower than "; shakes$
REM the >= and <= operators can also be used, & behave as expected
:
REM string comparison is case-sensitive by default, and BBC BASIC
REM does not provide built-in functions to convert to all upper
REM or all lower case; but it is easy enough to define one
:
IF FN_upper(shav$) = FN_upper(shakes$) THEN PRINT "The two strings are equal (disregarding case)" ELSE PRINT "The two strings are not equal (even disregarding case)"
END
:
DEF FN_upper(s$)
LOCAL i%, ns$
ns$ = ""
FOR i% = 1 TO LEN s$
IF ASC(MID$(s$, i%, 1)) >= ASC "a" AND ASC(MID$(s$, i%, 1)) <= ASC "z" THEN ns$ += CHR$(ASC(MID$(s$, i%, 1)) - &20) ELSE ns$ += MID$(s$, i%, 1)
NEXT
= ns$</syntaxhighlight>
{{out}}
<pre>The two strings are not equal
The two strings are unequal
Shaw, George Bernard is lexically higher than Shakespeare, William
Shaw, George Bernard is not lexically lower than Shakespeare, William
The two strings are not equal (even disregarding case)</pre>
 
=={{header|Bracmat}}==
Line 1,858:
assert(s.cmp("ABCD") == 1); // case sensitive
}</syntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
 
procedure ShowCompares(Memo: TMemo; S1,S2: string);
begin
if S1=S2 then Memo.Lines.Add(Format('"%s" is exactly equal to "%s"',[S1,S2]));
if S1<>S2 then Memo.Lines.Add(Format('"%s" is not equal to "%s"',[S1,S2]));
if S1<S2 then Memo.Lines.Add(Format('"%s" is less than "%s"',[S1,S2]));
if S1<=S2 then Memo.Lines.Add(Format('"%s" is less than or equal to "%s"',[S1,S2]));
if S1>S2 then Memo.Lines.Add(Format('"%s" is greater than "%s"',[S1,S2]));
if S1>=S2 then Memo.Lines.Add(Format('"%s" is greater than or equal to "%s"',[S1,S2]));
if AnsiSameText(S1, S2) then Memo.Lines.Add(Format('"%s" is case insensitive equal to "%s"',[S1,S2]));
Memo.Lines.Add(Format('"%s" "%s" case sensitive different = %d',[S1,S2,AnsiCompareStr(S1,S2)]));
Memo.Lines.Add(Format('"%s" "%s" case insensitive different = %d',[S1,S2,AnsiCompareText(S1,S2)]));
Memo.Lines.Add(Format('"%s" is found at Index %d in "%s"',[S1,Pos(S1,S2),S2]));
end;
 
 
procedure ShowStringCompares(Memo: TMemo);
begin
ShowCompares(Memo,'Equal', 'Equal');
ShowCompares(Memo,'Case', 'CASE');
ShowCompares(Memo,'91', '1234');
ShowCompares(Memo,'boy', 'cowboy');
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
"Equal" is exactly equal to "Equal"
"Equal" is less than or equal to "Equal"
"Equal" is greater than or equal to "Equal"
"Equal" is case insensitive equal to "Equal"
"Equal" "Equal" case sensitive different = 0
"Equal" "Equal" case insensitive different = 0
"Equal" is found at Index 1 in "Equal"
"Case" is not equal to "CASE"
"Case" is greater than "CASE"
"Case" is greater than or equal to "CASE"
"Case" is case insensitive equal to "CASE"
"Case" "CASE" case sensitive different = -1
"Case" "CASE" case insensitive different = 0
"Case" is found at Index 0 in "CASE"
"91" is not equal to "1234"
"91" is greater than "1234"
"91" is greater than or equal to "1234"
"91" "1234" case sensitive different = 1
"91" "1234" case insensitive different = 1
"91" is found at Index 0 in "1234"
"boy" is not equal to "cowboy"
"boy" is less than "cowboy"
"boy" is less than or equal to "cowboy"
"boy" "cowboy" case sensitive different = -1
"boy" "cowboy" case insensitive different = -1
"boy" is found at Index 4 in "cowboy"
Elapsed Time: 41.211 ms.
 
</pre>
 
=={{header|Dyalect}}==
Line 1,890 ⟶ 1,955:
'cat' is lexically before 'dog'.
'cat' is not lexically after 'dog'.
</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight lang="easylang">
a$ = "hello"
if a$ = "hello"
print "equal"
.
if a$ <> "hello2"
print "not equal"
.
if strcmp a$ "hello" = 0
print "equal"
.
if strcmp a$ "world" < 0
print "lexically before"
.
if number "10" > number "2"
print "numerically after"
.
</syntaxhighlight>
 
=={{header|Ecstasy}}==
In Ecstasy, strings are objects, like all values. Any class, including classes like <code>Int</code> and <code>String</code>, can provide operator support by annotating the methods that represent those operators. The result is simple uniformity of how types are defined, including their operators. String comparisons rely on these operators:
 
<syntaxhighlight lang="ecstasy">
module StringComparisons {
void run() {
@Inject Console console;
import ecstasy.collections.CaseInsensitive;
 
String[] tests = ["dog", "cat", "Dog"];
String s1 = tests[0];
for (String s2 : tests) {
// Comparing two strings for exact equality
if (s1 == s2) {
console.print($"{s1} == {s2}");
}
 
// Comparing two strings for inequality
if (s1 != s2) {
console.print($"{s1} != {s2}");
}
 
// Comparing two strings to see if one is lexically ordered
// before the other
if (s1 < s2) {
console.print($"{s1} < {s2}");
}
 
// Comparing two strings to see if one is lexically ordered
// after the other
if (s1 > s2) {
console.print($"{s1} > {s2}");
}
 
// How to achieve both case sensitive comparisons and case
// insensitive comparisons within the language
 
if (CaseInsensitive.areEqual(s1, s2)) {
console.print($"{s1} == {s2} (case-insensitive)");
} else {
console.print($"{s1} != {s2} (case-insensitive)");
}
 
switch (CaseInsensitive.compare(s1, s2)) {
case Lesser:
console.print($"{s1} < {s2} (case-insensitive)");
break;
case Equal:
// already covered this one above
assert CaseInsensitive.areEqual(s1, s2);
break;
case Greater:
console.print($"{s1} > {s2} (case-insensitive)");
break;
}
}
}
}
</syntaxhighlight>
 
{{out}}
<pre>
dog == dog
dog == dog (case-insensitive)
dog != cat
dog > cat
dog != cat (case-insensitive)
dog > cat (case-insensitive)
dog != Dog
dog > Dog
dog == Dog (case-insensitive)
</pre>
 
Line 2,392 ⟶ 2,550:
ge=: {.@/:@,&boxopen +. eq NB. lexically greater than or equal to
le=: -.@{.@/:@,&boxopen NB. lexically less than or equal to</syntaxhighlight>
 
Note that <code>boxopen</code> is used here so that these operations do not distinguish between the types <i>sequence of characters</i> and <i>boxed sequence of characters</i>. If distinguishing between these types would be desirable, <code>boxopen</code> should be replaced with <code>></code> or a separate test should also be used, such as <code>-:&datatype</code>.
 
'''Usage:'''
Line 2,504 ⟶ 2,664:
 
=={{header|jq}}==
jq strings are JSON strings. The jq comparison operators (==, !=, <, <=, >=, >) can be used to compare strings or indeed any JSON entities. Similarly, jq's <tt>sort</tt> and <tt>unique</tt> filters can be used to sort strings. The ordering of strings is determined by the Unicode codepoints.
 
<syntaxhighlight lang="jq"># Comparing two strings for exact equality:
Line 2,517 ⟶ 2,677:
 
# > is the inverse of < </syntaxhighlight>
jq provides `ascii_downcase` and `ascii_upcase` for ASCII case conversion.
Currently, jq does not have any "toupper" or "tolower" case conversion, but it is easy to define jq equivalents of ruby's downcase and upcase:<syntaxhighlight lang="jq">
# Only characters A to Z are affected
def downcase:
explode | map( if 65 <= . and . <= 90 then . + 32 else . end) | implode;
 
# Only characters a to z are affected
def upcase:
explode | map( if 97 <= . and . <= 122 then . - 32 else . end) | implode;</syntaxhighlight>
With the caveat that these are what they are, case-insensitive comparisons can be achieved as illustrated by this example:
<syntaxhighlight lang="jq">("AtoZ" | upcaseascii_upcase) == ("atoz" | upcaseascii_upcase) # true</syntaxhighlight>
Numeric strings are treated as any other JSON strings.
 
jq has an extensive library of built-in functions for handling strings. The most recent versions of jq (since 1.4) also have extensive support for PCRE regular expressions (regex), including named captures. Pleaseand seean [http://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions|jqoption Builtinto Operatorsturn andcase-sensitivity Functions]off. for details.
Please see [http://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions|jq Builtin Operators and Functions] for details.
 
=={{header|Julia}}==
Line 3,589 ⟶ 3,742:
The generic relationship of Num '5.1' and Rat '5.1' is Same
The numeric relationship of Num '5.1' and Rat '5.1' is Same</pre>
 
=== Unicode normalization by default ===
 
Be aware that Raku applies normalization (Unicode NFC form (Normalization Form Canonical)) by default to all input and output except for file names [https://docs.raku.org/language/unicode See docs]. Raku follows the Unicode spec. Raku follows '''all''' of the Unicode spec, including parts that some people don't like. There are some graphemes for which the Unicode consortium has specified that the NFC form is a different (though usually visually identical) grapheme. Referred to in [https://www.unicode.org/reports/tr15 Unicode standard annex #15] as '''Canonical Equivalence'''. Raku adheres to that spec.
 
One that people seem to get hung up on is the Kelvin symbol "K" getting automatically converted to ASCII uppercase "K".
 
<syntaxhighlight lang="raku" line>say "\c[KELVIN SIGN]".uniname;
# => LATIN CAPITAL LETTER K
 
my $kelvin = "\c[KELVIN SIGN]";
my $k = "\c[LATIN CAPITAL LETTER K]";
say ($kelvin eq $k); # True, lexically equal
say ($kelvin eqv $k); # True, generically equal
say ($kelvin === $k); # True, identical objects</syntaxhighlight>
 
In most programming language the previous two objects wouldn't be equivalent, but since Raku follows the Unicode specification, and normalization is applied automatically, they show up as equivalent.
 
It's officially identified as a possible trap for string handling. [https://docs.raku.org/language/traps#All_text_is_normalized_by_default See docs].
 
=={{header|Relation}}==
Line 3,791 ⟶ 3,963:
</syntaxhighlight>
 
=={{header|RPL}}==
Equality can be tested either with <code>==</code> or <code>SAME</code> operators:
"ab" "abc" ==
returns 0 (false).
 
To test inequality:
"ab" "abc" ≠
returns 1 (true).
 
Lexical order can be checked with <code><</code>, <code>≤</code>, <code>></code> or <code> ≥</code> operators.
"ab" "abc" ≤
returns also 1 (true).
All the above tests are case-sensitive.
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">method_names = [:==,:!=, :>, :>=, :<, :<=, :<=>, :casecmp]
Line 4,392 ⟶ 4,577:
 
Case insensitive comparisons can be achieved by converting both strings to the same case before the comparisons are made.
<syntaxhighlight lang="ecmascriptwren">import "./str" for Str
 
var compareStrings = Fn.new { |a, b, sens|
162

edits