String matching

String matching
You are encouraged to solve this task according to the task description, using any language you may know.

Basic Data Operation
This is a basic data operation. It represents a fundamental action on a basic data type.

You may see other such operations in the Basic Data Operations category, or:

Integer Operations
Arithmetic | Comparison

Boolean Operations
Bitwise | Logical

String Operations
Concatenation | Interpolation | Comparison | Matching

Memory Operations

Given two strings, demonstrate the following three types of string matching:

1.   Determining if the first string starts with second string
2.   Determining if the first string contains the second string at any location
3.   Determining if the first string ends with the second string

Optional requirements:

1.   Print the location of the match for part 2
2.   Handle multiple occurrences of a string for part 2.

360 Assembly

`*        String matching           04/04/2017STRMATCH CSECT         USING  STRMATCH,R15         XPRNT  SS,L'SS*         CLC    SS(L'S1),S1         BNE    NOT1         XPRNT  =C'-- STARTS WITH',14         XPRNT  S1,L'S1NOT1     EQU    **         CLC    SS+L'SS-L'S2(L'S2),S2         BNE    NOT2         XPRNT  =C'-- ENDS WITH',12         XPRNT  S2,L'S2NOT2     EQU    **         LA     R0,L'SS-L'S3+1         LA     R1,SSLOOP     CLC    0(L'S3,R1),S3         BNE    NOT3         XPRNT  =C'-- CONTAINS',11         XPRNT  S3,L'S3NOT3     LA     R1,1(R1)         BCT    R0,LOOP*         BR     R14SS       DC     CL6'ABCDEF'S1       DC     CL2'AB'S2       DC     CL2'EF'S3       DC     CL2'CD'PG       DC     CL80' '         YREGS         END    STRMATCH`
Output:
```ABCDEF
-- STARTS WITH
AB
-- ENDS WITH
EF
-- CONTAINS
CD
```

` with Ada.Strings.Fixed;  use Ada.Strings.Fixed;with Ada.Text_IO;        use Ada.Text_IO; procedure Match_Strings is   S1 : constant String := "abcd";   S2 : constant String := "abab";   S3 : constant String := "ab";begin   if S1'Length >= S3'Length and then S1 (S1'First..S1'First + S3'Length - 1) = S3 then      Put_Line (''' & S1 & "' starts with '" & S3 & ''');   end if;   if S2'Length >= S3'Length and then S2 (S2'Last - S3'Length + 1..S2'Last) = S3 then      Put_Line (''' & S2 & "' ends with '" & S3 & ''');   end if;   Put_Line (''' & S3 & "' first appears in '" & S1 & "' at" & Integer'Image (Index (S1, S3)));   Put_Line   (  ''' & S3 & "' appears in '" & S2 & ''' &      Integer'Image (Ada.Strings.Fixed.Count (S2, S3)) & " times"   );end Match_Strings; `
Output:
```'abcd' starts with 'ab'
'abab' ends with 'ab'
'ab' first appears in 'abcd' at 1
'ab' appears in 'abab' 2 times
```

Aime

`text s, t;data b; s = "Bangkok";t = "Bang"; b_cast(b, s); o_form("starts with, embeds, ends with \"~\": ~, ~, ~\n", t, b_seek(b, t) == 0,       b_seek(b, t) != -1,       b_seek(b, t) != -1 && b_seek(b, t) + length(t) == length(s)); t = "ok"; o_form("starts with, embeds, ends with \"~\": ~, ~, ~\n", t, b_seek(b, t) == 0,       b_seek(b, t) != -1,       b_seek(b, t) != -1 && b_seek(b, t) + length(t) == length(s)); t = "Summer"; o_form("starts with, embeds, ends with \"~\": ~, ~, ~\n", t, b_seek(b, t) == 0,       b_seek(b, t) != -1,       b_seek(b, t) != -1 && b_seek(b, t) + length(t) == length(s));`
Output:
```starts with, embeds, ends with "Bang": 1, 1, 0
starts with, embeds, ends with "ok": 0, 1, 1
starts with, embeds, ends with "Summer": 0, 0, 0```

ALGOL 68

Translation of: python
Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
`# define some appropriate OPerators #PRIO STARTSWITH = 5, ENDSWITH = 5;OP STARTSWITH = (STRING str, prefix)BOOL: # assuming LWB = 1 #  IF UPB str < UPB prefix THEN FALSE ELSE str[:UPB prefix]=prefix FI;OP ENDSWITH = (STRING str, suffix)BOOL: # assuming LWB = 1 #  IF UPB str < UPB suffix THEN FALSE ELSE str[UPB str-UPB suffix+1:]=suffix FI; INT loc, loc2; print((  "abcd" STARTSWITH "ab", # returns TRUE #  "abcd" ENDSWITH "zn", # returns FALSE #  string in string("bb",loc,"abab"), # returns FALSE #  string in string("ab",loc,"abab"), # returns TRUE #  (string in string("bb",loc,"abab")|loc|-1), # returns -1 #  (string in string("ab",loc,"abab")|loc|-1), # returns +1 #  (string in string("ab",loc2,"abab"[loc+1:])|loc+loc2|-1) # returns +3 #))`
Output:
```TFFT         -1         +1         +3
```

AutoHotkey

` String1 = abcdString2 = abab If (SubStr(String1,1,StrLen(String2)) = String2) MsgBox, "%String1%" starts with "%String2%".IfInString, String1, %String2%{ Position := InStr(String1,String2) StringReplace, String1, String1, %String2%, %String2%, UseErrorLevel MsgBox, "%String1%" contains "%String2%" at position %Position%`, and appears %ErrorLevel% times.}StringRight, TempVar, String1, StrLen(String2)If TempVar = %String2% MsgBox, "%String1%" ends with "%String2%". `

AutoIt

`\$string1 = "arduinoardblobard"\$string2 = "ard" ; == Determining if the first string starts with second stringIf StringLeft(\$string1, StringLen(\$string2)) = \$string2 Then	ConsoleWrite("1st string starts with 2nd string." & @CRLF)Else	ConsoleWrite("1st string does'nt starts with 2nd string." & @CRLF)EndIf ; == Determining if the first string contains the second string at any location; == Print the location of the match for part 2; == Handle multiple occurrences of a string for part 2\$start = 1\$count = 0\$pos = StringInStr(\$string1, \$string2)While \$pos	\$count += 1	ConsoleWrite("1st string contains 2nd string at position: " & \$pos & @CRLF)	\$pos = StringInStr(\$string1, \$string2, 0, 1, \$start + \$pos + StringLen(\$string2))WEndIf \$count = 0 Then ConsoleWrite("1st string does'nt contain 2nd string." & @CRLF) ; == Determining if the first string ends with the second stringIf StringRight(\$string1, StringLen(\$string2)) = \$string2 Then	ConsoleWrite("1st string ends with 2nd string." & @CRLF)Else	ConsoleWrite("1st string does'nt ends with 2nd string." & @CRLF)EndIf  `

AWK

`#!/usr/bin/awk -f{    if (\$1 ~ "^"\$2) {	print \$1" begins with "\$2;    } else {	print \$1" does not begin with "\$2;    }     if (\$1 ~ \$2) {	print \$1" contains "\$2;    } else {	print \$1" does not contain "\$2;    }     if (\$1 ~ \$2"\$") {	print \$1" ends with "\$2;    } else {	print \$1" does not end with "\$2;    }} `

BASIC

Works with: QBasic
`first\$ = "qwertyuiop" 'Determining if the first string starts with second stringsecond\$ = "qwerty"IF LEFT\$(first\$, LEN(second\$)) = second\$ THEN    PRINT "'"; first\$; "' starts with '"; second\$; "'"ELSE    PRINT "'"; first\$; "' does not start with '"; second\$; "'"END IF 'Determining if the first string contains the second string at any location'Print the location of the match for part 2second\$ = "wert"x = INSTR(first\$, second\$)IF x THEN    PRINT "'"; first\$; "' contains '"; second\$; "' at position "; xELSE    PRINT "'"; first\$; "' does not contain '"; second\$; "'"END IF ' Determining if the first string ends with the second stringsecond\$ = "random garbage"IF RIGHT\$(first\$, LEN(second\$)) = second\$ THEN    PRINT "'"; first\$; "' ends with '"; second\$; "'"ELSE    PRINT "'"; first\$; "' does not end with '"; second\$; "'"END IF  `
Output:
```'qwertyuiop' starts with 'qwerty'
'qwertyuiop' contains 'wert' at position  2
'qwertyuiop' does not end with 'random garbage'
```

Applesoft BASIC

`10 A\$ = "THIS, THAT, AND THE OTHER THING"20 S\$ = "TH"30 DEF FN S(P) = MID\$(A\$, P, LEN(S\$)) = S\$40 PRINT A\$ : PRINT 110 S\$(1) = "STARTS"120 S\$(0) = "DOES NOT START"130 PRINT S\$(FN S(1))" WITH "S\$ : PRINT 210 R\$ = "" : FOR I = 1 TO LEN(A\$) - LEN(S\$) : IF FN S(I) THEN R\$ = R\$ + STR\$(I) + " "220 NEXT I230 IF LEN(R\$) = 0 THEN PRINT "DOES NOT CONTAIN "S\$240 IF LEN(R\$) THEN PRINT "CONTAINS "S\$" LOCATED AT POSITION "R\$250 PRINT 310 E\$(1) = "ENDS"320 E\$(0) =  "DOES NOT END"330 PRINT E\$(FN S(LEN(A\$) - LEN(S\$) + 1))" WITH "S\$`

Batch File

`::NOTE #1: This implementation might crash, or might not work properly if::you put some of the CMD special characters (ex. %,!, etc) inside the strings.::::NOTE #2: The comparisons here are case-SENSITIVE.::NOTE #3: Spaces in strings are considered. @echo offsetlocal enabledelayedexpansion::The main things...set "str1=qwertyuiop"set "str2=qwerty"call :str2_lngthcall :matchbegin set "str1=qweiuoiocghiioyiocxiisfguiioiuygvd"set "str2=io"call :str2_lngthcall :matchcontain set "str1=blablabla"set "str2=bbla"call :str2_lngthcall :matchend echo.pauseexit /b 0::/The main things.::The functions...:matchbeginecho.if "!str1:~0,%length%!"=="!str2!" (	echo "%str1%" begins with "%str2%".) else (	echo "%str1%" does not begin with "%str2%".)goto :EOF :matchcontainecho.set curr=0&set exist=0:scanchrloopif "!str1:~%curr%,%length%!"=="" (	if !exist!==0 echo "%str1%" does not contain "%str2%".	goto :EOF) if "!str1:~%curr%,%length%!"=="!str2!" (	echo "%str1%" contains "%str2%". ^(in Position %curr%^)	set exist=1)set /a curr+=1&goto scanchrloop :matchendecho.if "!str1:~-%length%!"=="!str2!" (	echo "%str1%" ends with "%str2%".) else (	echo "%str1%" does not end with "%str2%".)goto :EOF :str2_lngthset length=0:loopif "!str2:~%length%,1!"=="" goto :EOFset /a length+=1goto loop::/The functions.`
Output:
```"qwertyuiop" begins with "qwerty".

"qweiuoiocghiioyiocxiisfguiioiuygvd" contains "io". (in Position 6)
"qweiuoiocghiioyiocxiisfguiioiuygvd" contains "io". (in Position 12)
"qweiuoiocghiioyiocxiisfguiioiuygvd" contains "io". (in Position 15)
"qweiuoiocghiioyiocxiisfguiioiuygvd" contains "io". (in Position 26)

"blablabla" does not end with "bbla".

Press any key to continue . . .```

BBC BASIC

`      first\$ = "The fox jumps over the dog"       FOR test% = 1 TO 3        READ second\$        starts% = FN_first_starts_with_second(first\$, second\$)        IF starts% PRINT """" first\$ """ starts with """ second\$ """"        ends% = FN_first_ends_with_second(first\$, second\$)        IF ends% PRINT """" first\$ """ ends with """ second\$ """"        where% = FN_first_contains_second_where(first\$, second\$)        IF where% PRINT """" first\$ """ contains """ second\$ """ at position " ; where%        howmany% = FN_first_contains_second_howmany(first\$, second\$)        IF howmany% PRINT """" first\$ """ contains """ second\$ """ " ; howmany% " time(s)"      NEXT      DATA "The", "he", "dog"      END       DEF FN_first_starts_with_second(A\$, B\$)      = B\$ = LEFT\$(A\$, LEN(B\$))       DEF FN_first_ends_with_second(A\$, B\$)      = B\$ = RIGHT\$(A\$, LEN(B\$))       DEF FN_first_contains_second_where(A\$, B\$)      = INSTR(A\$, B\$)       DEF FN_first_contains_second_howmany(A\$, B\$)      LOCAL I%, N% : I% = 0      REPEAT        I% = INSTR(A\$, B\$, I%+1)        IF I% THEN N% += 1      UNTIL I% = 0      = N% `
Output:
```"The fox jumps over the dog" starts with "The"
"The fox jumps over the dog" contains "The" at position 1
"The fox jumps over the dog" contains "The" 1 time(s)
"The fox jumps over the dog" contains "he" at position 2
"The fox jumps over the dog" contains "he" 2 time(s)
"The fox jumps over the dog" ends with "dog"
"The fox jumps over the dog" contains "dog" at position 24
"The fox jumps over the dog" contains "dog" 1 time(s)```

Bracmat

Bracmat does pattern matching in expressions `subject:pattern` and in strings `@(subject:pattern)`. The (sub)pattern `?` is a wild card.

`( (sentence="I want a number such that that number will be even.")& out\$(@(!sentence:I ?) & "sentence starts with 'I'" | "sentence does not start with 'I'")& out\$(@(!sentence:? such ?) & "sentence contains 'such'" | "sentence does not contain 'such'")& out\$(@(!sentence:? "even.") & "sentence ends with 'even.'" | "sentence does not end with 'even.'")& 0:?N& ( @(!sentence:? be (? & !N+1:?N & ~))  | out\$str\$("sentence contains " !N " occurrences of 'be'")  ))`

In the last line, Bracmat is forced by the always failing node `~` to backtrack until all occurrences of 'be' are found. Thereafter the pattern match expression fails. The interesting part is the side effect: while backtracking, the accumulator `N` keeps track of how many are found.

Output:
```sentence starts with 'I'
sentence contains 'such'
sentence ends with 'even.'
sentence contains 3 occurrences of 'be'```

C

Case sensitive matching:

`#include <string.h>#include <stdio.h> int startsWith(const char* container, const char* target){  size_t clen = strlen(container), tlen = strlen(target);  if (clen < tlen)    return 0;  return strncmp(container, target, tlen) == 0;} int endsWith(const char* container, const char* target){  size_t clen = strlen(container), tlen = strlen(target);  if (clen < tlen)    return 0;  return strncmp(container + clen - tlen, target, tlen) == 0;} int doesContain(const char* container, const char* target){  return strstr(container, target) != 0;} int main(void){  printf("Starts with Test ( Hello,Hell ) : %d\n", startsWith("Hello","Hell"));  printf("Ends with Test ( Code,ode ) : %d\n", endsWith("Code","ode"));  printf("Contains Test ( Google,msn ) : %d\n", doesContain("Google","msn"));   return 0;}`
Output:
```Starts with Test ( Hello,Hell ) : 1
Ends with Test ( Code,ode ) : 1
Contains Test ( Google,msn ) : 0```

Code without using string library to demonstrate how char strings are just pointers:

`#include <stdio.h> /* returns 0 if no match, 1 if matched, -1 if matched and at end */int s_cmp(const char *a, const char *b){        char c1 = 0, c2 = 0;        while (c1 == c2) {                c1 = *(a++);                if ('\0' == (c2 = *(b++)))                        return c1 == '\0' ? -1 : 1;        }        return 0;} /* returns times matched */int s_match(const char *a, const char *b){        int i = 0, count = 0;        printf("matching `%s' with `%s':\n", a, b);         while (a[i] != '\0') {                switch (s_cmp(a + i, b)) {                case -1:                        printf("matched: pos %d (at end)\n\n", i);                        return ++count;                case 1:                        printf("matched: pos %d\n", i);                        ++count;                        break;                }                i++;        }        printf("end match\n\n");        return count;} int main(){        s_match("A Short String", "ort S");        s_match("aBaBaBaBa", "aBa");        s_match("something random", "Rand");         return 0;}`
Output:
```matching `A Short String' with `ort S':
matched: pos 4
end match

matching `aBaBaBaBa' with `aBa':
matched: pos 0
matched: pos 2
matched: pos 4
matched: pos 6 (at end)

matching `something random' with `Rand':
end match```

C++

`#include <string>using namespace std; string s1="abcd";string s2="abab";string s3="ab";//Beginnings1.compare(0,s3.size(),s3)==0;//Ends1.compare(s1.size()-s3.size(),s3.size(),s3)==0;//Anywheres1.find(s2)//returns string::nposint loc=s2.find(s3)//returns 0loc=s2.find(s3,loc+1)//returns 2`

C#

Works with: Mono version 2.6
` class Program{	public static void Main (string[] args)	{		var value = "abcd".StartsWith("ab");		value = "abcd".EndsWith("zn"); //returns false		value = "abab".Contains("bb"); //returns false		value = "abab".Contains("ab"); //returns true		int loc = "abab".IndexOf("bb"); //returns -1		loc = "abab".IndexOf("ab"); //returns 0		loc = "abab".IndexOf("ab",loc+1); //returns 2	}} `

Clojure

Translation of: Java
`(def evals '((. "abcd" startsWith "ab")	     (. "abcd" endsWith "zn")	     (. "abab" contains "bb")	     (. "abab" contains "ab")	     (. "abab" indexOf "bb")	     (let [loc (. "abab" indexOf "ab")]	       (. "abab" indexOf "ab" (dec loc))))) user> (for [i evals] [i (eval i)])([(. "abcd" startsWith "ab") true] [(. "abcd" endsWith "zn") false] [(. "abab" contains "bb") false] [(. "abab" contains "ab") true] [(. "abab" indexOf "bb") -1] [(let [loc (. "abab" indexOf "ab")] (. "abab" indexOf "ab" (dec loc))) 0])`

CoffeeScript

This example uses string slices, but a better implementation might use indexOf for slightly better performance.

` matchAt = (s, frag, i) ->  s[i...i+frag.length] == frag startsWith = (s, frag) ->  matchAt s, frag, 0 endsWith = (s, frag) ->  matchAt s, frag, s.length - frag.length matchLocations = (s, frag) ->  (i for i in [0..s.length - frag.length] when matchAt s, frag, i) console.log startsWith "tacoloco", "taco" # trueconsole.log startsWith "taco", "tacoloco" # falseconsole.log startsWith "tacoloco", "talk" # falseconsole.log endsWith "tacoloco", "loco" # trueconsole.log endsWith "loco", "tacoloco" # falseconsole.log endsWith "tacoloco", "yoco" # falseconsole.log matchLocations "bababab", "bab" # [0,2,4]console.log matchLocations "xxx", "x" # [0,1,2] `

Common Lisp

` (defun starts-with-p (str1 str2)  "Determine whether `str1` starts with `str2`"  (let ((p (search str2 str1)))    (and p (= 0 p)))) (print (starts-with-p "foobar" "foo")) ; T (print (starts-with-p "foobar" "bar")) ; NIL (defun ends-with-p (str1 str2)  "Determine whether `str1` ends with `str2`"  (let ((p (mismatch str2 str1 :from-end T)))    (or (not p) (= 0 p)))) (print (ends-with-p "foobar" "foo")) ; NIL(print (ends-with-p "foobar" "bar")) ; T (defun containsp (str1 str2)  "Determine whether `str1` contains `str2`.   Instead of just returning T, return a list of starting locations   for every occurence of `str2` in `str1`"   (unless (string-equal str2 "")     (loop for p = (search str2 str1) then (search str2 str1 :start2 (1+ p))           while p            collect p))) (print (containsp "foobar" "oba")) ; (2)(print (containsp "ababaBa" "ba")) ; (1 3)(print (containsp "foobar" "x"))   ; NIL `

Component Pascal

BlackBox Component Builder

` MODULE StringMatch;IMPORT StdLog,Strings;CONST	strSize = 1024;	patSize = 256; TYPE 	Matcher* = POINTER TO LIMITED RECORD		str: ARRAY strSize OF CHAR;		pat: ARRAY patSize OF CHAR;		pos: INTEGER	END; PROCEDURE NewMatcher*(IN str: ARRAY OF CHAR): Matcher;VAR	m: Matcher;BEGIN	NEW(m);m.str := str\$;m.pos:= 0;	RETURN mEND NewMatcher; PROCEDURE (m: Matcher) Match*(IN pat: ARRAY OF CHAR): INTEGER,NEW;VAR 	pos: INTEGER;BEGIN	m.pat := pat\$; 	pos := m.pos;	Strings.Find(m.str,m.pat,pos,m.pos);	RETURN m.posEND Match; PROCEDURE (m: Matcher) Next*(): INTEGER, NEW;VAR	pos: INTEGER;BEGIN	pos := m.pos + LEN(m.pat\$);	Strings.Find(m.str,m.pat,pos,m.pos);	RETURN m.pos;END Next; (* Some Helper functions based on Strings module *)PROCEDURE StartsWith(IN str: ARRAY OF CHAR;IN pat: ARRAY OF CHAR): BOOLEAN;VAR	pos: INTEGER;BEGIN	Strings.Find(str,pat,0,pos);	RETURN pos = 0END StartsWith; PROCEDURE Contains(IN str: ARRAY OF CHAR;IN pat: ARRAY OF CHAR; OUT pos: INTEGER): BOOLEAN;BEGIN	Strings.Find(str,pat,0,pos);	RETURN pos >= 0END Contains; PROCEDURE EndsWith(IN str: ARRAY OF CHAR;IN pat: ARRAY OF CHAR): BOOLEAN;VAR	pos: INTEGER;BEGIN	Strings.Find(str,pat,0,pos);	RETURN pos + LEN(pat\$) = LEN(str\$)END EndsWith; PROCEDURE Do*;CONST	aStr = "abcdefghijklmnopqrstuvwxyz";VAR	pat: ARRAY 128 OF CHAR;	res: BOOLEAN;	at: INTEGER;	m: Matcher;BEGIN	(* StartsWith *)	pat := "abc";	StdLog.String(aStr + " startsWith " + pat + " :>");StdLog.Bool(StartsWith(aStr,pat));StdLog.Ln;	pat := "cba";	StdLog.String(aStr + " startsWith " + pat + " :>");StdLog.Bool(StartsWith(aStr,pat));StdLog.Ln;	pat := "def";	StdLog.String(aStr + " startsWith " + pat + " :>");StdLog.Bool(StartsWith(aStr,pat));StdLog.Ln;	StdLog.Ln;	(* Contains *)	pat := 'def';	StdLog.String(aStr + " contains " + pat + " :>");StdLog.Bool(Contains(aStr,pat,at));	StdLog.String(" at: ");StdLog.Int(at);StdLog.Ln;	pat := 'efd';	StdLog.String(aStr + " contains " + pat + " :>");StdLog.Bool(Contains(aStr,pat,at));	StdLog.String(" at: ");StdLog.Int(at);StdLog.Ln;		pat := 'abc';	StdLog.String(aStr + " contains " + pat + " :>");StdLog.Bool(Contains(aStr,pat,at));	StdLog.String(" at: ");StdLog.Int(at);StdLog.Ln;	pat := 'xyz';	StdLog.String(aStr + " contains " + pat + " :>");StdLog.Bool(Contains(aStr,pat,at));	StdLog.String(" at: ");StdLog.Int(at);StdLog.Ln;	StdLog.Ln;	(* EndsWith *)	pat := 'xyz';	StdLog.String(aStr + " endsWith " + pat + " :>");StdLog.Bool(EndsWith(aStr,pat));StdLog.Ln;	pat := 'zyx';	StdLog.String(aStr + " endsWith " + pat + " :>");StdLog.Bool(EndsWith(aStr,pat));StdLog.Ln;	pat := 'abc';	StdLog.String(aStr + " endsWith " + pat + " :>");StdLog.Bool(EndsWith(aStr,pat));StdLog.Ln;	pat:= 'def';	StdLog.String(aStr + " endsWith " + pat + " :>");StdLog.Bool(EndsWith(aStr,pat));StdLog.Ln;	StdLog.Ln; 	m := NewMatcher("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");	StdLog.String("Matching 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' against 'abc':> ");	StdLog.Ln;	StdLog.String("Match at: ");StdLog.Int(m.Match("abc"));StdLog.Ln;	StdLog.String("Match at: ");StdLog.Int(m.Next());StdLog.Ln;	StdLog.String("Match at: ");StdLog.Int(m.Next());StdLog.LnEND Do;END StringMatch. `

Execute: ^Q StringMatching.Do

Output:
```abcdefghijklmnopqrstuvwxyz startsWith abc :> \$TRUE
abcdefghijklmnopqrstuvwxyz startsWith cba :> \$FALSE
abcdefghijklmnopqrstuvwxyz startsWith def :> \$FALSE

abcdefghijklmnopqrstuvwxyz contains def :> \$TRUE at:  3
abcdefghijklmnopqrstuvwxyz contains efd :> \$FALSE at:  -1
abcdefghijklmnopqrstuvwxyz contains abc :> \$TRUE at:  0
abcdefghijklmnopqrstuvwxyz contains xyz :> \$TRUE at:  23

abcdefghijklmnopqrstuvwxyz endsWith xyz :> \$TRUE
abcdefghijklmnopqrstuvwxyz endsWith zyx :> \$FALSE
abcdefghijklmnopqrstuvwxyz endsWith abc :> \$FALSE
abcdefghijklmnopqrstuvwxyz endsWith def :> \$FALSE

Matching 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' against 'abc':>
Match at:  0
Match at:  26
Match at:  -1
```

D

`void main() {    import std.stdio;    import std.algorithm: startsWith, endsWith, find, countUntil;     "abcd".startsWith("ab").writeln;      // true    "abcd".endsWith("zn").writeln;        // false    "abab".find("bb").writeln;            // empty array (no match)    "abcd".find("bc").writeln;            // "bcd" (substring start                                           //        at match)    "abab".countUntil("bb").writeln;      // -1 (no match)    "abab".countUntil("ba").writeln;      //  1 (index of 1st match)     // std.algorithm.startsWith also works on arrays and ranges:    [1, 2, 3].countUntil(3).writeln;      //  2    [1, 2, 3].countUntil([2, 3]).writeln; //  1}`
Output:
```true
false

bcd
-1
1
2
1```

DCL

`\$ first_string = p1\$ length_of_first_string = f\$length( first_string )\$ second_string = p2\$ length_of_second_string = f\$length( second_string )\$ offset = f\$locate( second_string, first_string )\$ if offset .eq. 0\$ then\$  write sys\$output "first string starts with second string"\$ else\$  write sys\$output "first string does not start with second string"\$ endif\$ if offset .ne. length_of_first_string\$ then\$  write sys\$output "first string contains the second string at location ", offset\$ else\$  write sys\$output "first string does not contain the second string at any location"\$ endif\$ temp = f\$extract( length_of_first_string - length_of_second_string, length_of_second_string, first_string )\$ if second_string .eqs. temp\$ then\$  write sys\$output "first string ends with the second string"\$ else\$  write sys\$output "first string does not end with the second string"\$ endif`
Output:
```\$ @string_matching efabcdef ef
first string starts with second string
first string contains the second string at location 0
first string ends with the second string
\$ @string_matching efabcdef ab
first string contains the second string at location 2
first string does not end with the second string
\$ @string_matching efabcdef def
first string contains the second string at location 5
first string ends with the second string
\$ @string_matching efabcdef defx
first string does not contain the second string at any location
first string does not end with the second string```

Delphi

`program CharacterMatching; {\$APPTYPE CONSOLE} uses StrUtils; begin  WriteLn(AnsiStartsText('ab', 'abcd')); // True  WriteLn(AnsiEndsText('zn', 'abcd')); // False  WriteLn(AnsiContainsText('abcd', 'bb')); // False  Writeln(AnsiContainsText('abcd', 'ab')); // True  WriteLn(Pos('ab', 'abcd')); // 1end.`

E

`def f(string1, string2) {    println(string1.startsWith(string2))     var index := 0    while ((index := string1.startOf(string2, index)) != -1) {        println(`at \$index`)        index += 1    }     println(string1.endsWith(string2))}`

EchoLisp

` (string-suffix? "nette" "Antoinette") → #t(string-prefix? "Simon" "Simon & Garfunkel") → #t (string-match "Antoinette" "net") → #t ;; contains(string-index "net" "Antoinette") → 5  ;; substring location `

Elena

ELENA 3.4 :

`import extensions. public program[    var s := "abcd".     console printLine(s," starts with ab: ",s startingWith:"ab").    console printLine(s," starts with cd: ",s startingWith:"cd").     console printLine(s," ends with ab: ",s endingWith:"ab").    console printLine(s," ends with cd: ",s endingWith:"cd").     console printLine(s," contains ab: ",s containing:"ab").    console printLine(s," contains bc: ",s containing:"bc").    console printLine(s," contains cd: ",s containing:"cd").    console printLine(s," contains az: ",s containing:"az").     console printLine(s," index of az: ",s indexOf:"az" at:0).    console printLine(s," index of cd: ",s indexOf:"cd" at:0).    console printLine(s," index of bc: ",s indexOf:"bc" at:0).    console printLine(s," index of ab: ",s indexOf:"ab" at:0).     console readChar]`

Elixir

The String module has functions that cover the base requirements.

`s1 = "abcd"s2 = "adab"s3 = "ab" String.starts_with?(s1, s3)# => trueString.starts_with?(s2, s3)# => false String.contains?(s1, s3)# => trueString.contains?(s2, s3)# => true String.ends_with?(s1, s3)# => falseString.ends_with?(s2, s3)# => true  # Optional requirements:Regex.run(~r/#{s3}/, s1, return: :index)# => [{0, 2}]Regex.run(~r/#{s3}/, s2, return: :index)# => [{2, 2}] Regex.scan(~r/#{s3}/, "abcabc", return: :index)# => [[{0, 2}], [{3, 2}]]`

Emacs Lisp

` (defun match (word str)  (progn     (setq regex (format "^%s.*\$" word) )     (if (string-match regex str)	(insert (format "%s found in beginning of: %s\n" word str) )      (insert (format "%s not found in beginning of: %s\n" word str) ))     (setq pos (string-match word str) )     (if pos	(insert (format "%s found at position %d in: %s\n" word pos str) )      (insert (format "%s not found in: %s\n" word str) ))     (setq regex (format "^.*%s\$" word) )     (if (string-match regex str)	(insert (format "%s found in end of: %s\n" word str) )      (insert (format "%s not found in end of: %s\n" word str) )))) (setq string "before center after") (progn  (match "center" string)  (insert "\n")  (match "before" string)  (insert "\n")  (match "after" string) ) `

Output:

```center not found in beginning of: before center after
center found at position 7 in: before center after

before found in beginning of: before center after
before found at position 0 in: before center after

after found at position 14 in: before center after
after found in end of: before center after
```

Erlang

` -module(character_matching).-export([starts_with/2,ends_with/2,contains/2]). %% Both starts_with and ends_with are mappings to 'lists:prefix/2' and                                                                                                                                                                                                                %% 'lists:suffix/2', respectively.                                                                                                                                                                                                                                                     starts_with(S1,S2) ->    lists:prefix(S2,S1). ends_with(S1,S2) ->    lists:suffix(S2,S1). contains(S1,S2) ->    contains(S1,S2,1,[]). %% While S1 is at least as long as S2 we check if S2 is its prefix,                                                                                                                                                                                                                   %% storing the result if it is. When S1 is shorter than S2, we return                                                                                                                                                                                                                 %% the result. NB: this will work on any arbitrary list in erlang                                                                                                                                                                                                                     %% since it makes no distinction between strings and lists.                                                                                                                                                                                                                           contains([_|T]=S1,S2,N,Acc) when length(S2) =< length(S1) ->    case starts_with(S1,S2) of        true ->            contains(T,S2,N+1,[N|Acc]);        false ->            contains(T,S2,N+1,Acc)    end;contains(_S1,_S2,_N,Acc) ->    Acc. `

Euphoria

`sequence first, secondinteger x first = "qwertyuiop" -- Determining if the first string starts with second stringsecond = "qwerty"if match(second, first) = 1 then    printf(1, "'%s' starts with '%s'\n", {first, second})else    printf(1, "'%s' does not start with '%s'\n", {first, second})end if -- Determining if the first string contains the second string at any location-- Print the location of the match for part 2second = "wert"x = match(second, first)if x then    printf(1, "'%s' contains '%s' at position %d\n", {first, second, x})else    printf(1, "'%s' does not contain '%s'\n", {first, second})end if -- Determining if the first string ends with the second stringsecond = "uio"if length(second)<=length(first) and match_from(second, first, length(first)-length(second)+1) then    printf(1, "'%s' ends with '%s'\n", {first, second})else    printf(1, "'%s' does not end with '%s'\n", {first, second})end if`
Output:
```'qwertyuiop' starts with 'qwerty'
'qwertyuiop' contains 'wert' at position 2
'qwertyuiop' does not end with 'uio'
```

F#

`[<EntryPoint>]let main args =     let text = "一二三四五六七八九十"    let starts = "一二"    let ends = "九十"    let contains = "五六"    let notContains = "百"     printfn "text = %A" text    printfn "starts with %A: %A" starts (text.StartsWith(starts))    printfn "starts with %A: %A" ends (text.StartsWith(ends))    printfn "ends with %A: %A" ends (text.EndsWith(ends))    printfn "ends with %A: %A" starts (text.EndsWith(starts))    printfn "contains %A: %A" contains (text.Contains(contains))    printfn "contains %A: %A" notContains (text.Contains(notContains))    printfn "substring %A begins at position %d (zero-based)" contains (text.IndexOf(contains))    let text2 = text + text    printfn "text = %A" text2    Seq.unfold (fun (n : int) ->            let idx = text2.IndexOf(contains, n)            if idx < 0 then None else Some (idx, idx+1)) 0    |> Seq.iter (printfn "substring %A begins at position %d (zero-based)" contains)    0`
Output:
```text = "一二三四五六七八九十"
starts with "一二": true
starts with "九十": false
ends with "九十": true
ends with "一二": false
contains "五六": true
contains "百": false
substring "五六" begins at position 4 (zero-based)
text = "一二三四五六七八九十一二三四五六七八九十"
substring "五六" begins at position 4 (zero-based)
substring "五六" begins at position 14 (zero-based)```

Factor

Does `cheesecake` start with `cheese`?

`"cheesecake" "cheese" head?   ! t`

Does `cheesecake` contain `sec` at any location?

`"sec" "cheesecake" subseq?   ! t`

Does `cheesecake` end with `cake`?

`"cheesecake" "cake" tail?   ! t`

Where in `cheesecake` is the leftmost `sec`?

`"sec" "cheesecake" subseq-start   ! 4`

Where in `Mississippi` are all occurrences of `iss`?

`USE: regexp"Mississippi" "iss" <regexp> all-matching-slices [ from>> ] map   ! { 1 4 }`

Falcon

'VBA/Python programmer's approach. I'm just a junior Falconeer but this code seems falconic

` /* created by Aykayayciti Earl Lamont MontgomeryApril 9th, 2018 */ s1 = "Naig Ialocin Olracnaig"s2 = "Naig" var = s1.startsWith(s2) ? s1 + " starts with " + s2 : s1 + " does not start with " + s2> var s2 = "loc"var = s2 in s1 ? @ "\$s1 contains \$s2" : @ "\$s1 does not contain \$s2"> var > s1.endsWith(s2) ? @ "s1 ends with \$s2" : @ "\$s1 does not end with \$s2" `
Output:
```Naig Ialocin Olracnaig starts with Naig
Naig Ialocin Olracnaig contains loc
Naig Ialocin Olracnaig does not end with loc
[Finished in 1.2s]
```

Fantom

Fantom provides several self-explanatory string-matching methods:

• `startsWith`
• `endsWith`
• `contains`
• `index` (takes an optional index, for the start position)
• `indexIgnoreCase` (like above, ignoring case for ASCII characters)
• `indexr` (start search from end of string, with an optional index)
• `indexrIgnoreCase` (like above, ignoring case for ASCII characters)
` class Main{  public static Void main ()  {    string := "Fantom Language"    echo ("String is: " + string)    echo ("does string start with 'Fantom'? " + string.startsWith("Fantom"))    echo ("does string start with 'Language'? " + string.startsWith("Language"))    echo ("does string contain 'age'? " + string.contains("age"))    echo ("does string contain 'page'? " + string.contains("page"))    echo ("does string end with 'Fantom'? " + string.endsWith("Fantom"))    echo ("does string end with 'Language'? " + string.endsWith("Language"))     echo ("Location of 'age' is: " + string.index("age"))    posn := string.index ("an")    echo ("First location of 'an' is: " + posn)    posn = string.index ("an", posn+1)    echo ("Second location of 'an' is: " + posn)    posn = string.index ("an", posn+1)    if (posn == null) echo ("No third location of 'an'")  }} `
Output:
```String is: Fantom Language
does string contain 'age'? true
does string contain 'page'? false
does string end with 'Fantom'? false
does string end with 'Language'? true
Location of 'age' is: 12
First location of 'an' is: 1
Second location of 'an' is: 8
No third location of 'an'
```

FBSL

`#APPTYPE CONSOLE DIM s = "roko, mat jane do" IF LEFT(s, 4) = "roko" THEN PRINT STRENC(s), " starts with ", STRENC("roko")IF INSTR(s, "mat") THEN PRINT STRENC(s), " contains ", STRENC("mat"), " at ", INSTRIF RIGHT(s, 2) = "do" THEN PRINT STRENC(s), " ends with ", STRENC("do")PRINT STRENC(s), " contains ", STRENC("o"), " at the following locations:", InstrEx(s, "o") PAUSE SUB InstrEx(mane, match)    INSTR = 0    WHILE INSTR(mane, match, INSTR + 1): PRINT " ", INSTR;: WENDEND SUB `
Output:
```"roko, mat jane do" starts with "roko"
"roko, mat jane do" contains "mat" at 7
"roko, mat jane do" ends with "do"
"roko, mat jane do" contains "o" at the following locations: 2 4 17

Press any key to continue...```

Forth

`: starts-with ( a l a2 l2 -- ? )  tuck 2>r min 2r> compare 0= ;: ends-with ( a l a2 l2 -- ? )  tuck 2>r negate over + 0 max /string 2r> compare 0= ;\ use SEARCH ( a l a2 l2 -- a3 l3 ? ) for contains`

Fortran

Fortran does not offer a string type, but since F77 it has been possible to use a CHARACTER variable, of some specified size, whose size may be accessed via the LEN function. When passed as a parameter, a secret additional parameter specifies its size and so string-like usage is possible. Character matching is case sensitive, and, trailing spaces are ignored so that "xx" and "xx " are deemed equal. The function INDEX(text,target) determines the first index in text where target matches, and returns zero if there is no such match. Unfortunately, the function does not allow the specification of a starting position for a search, as to find any second and further matches. One must specify something like `INDEX(text(5:),target)` to start with position five, and then deal with the resulting offsets needed to relate the result to positions within the parameter. On the other hand, since there is no "length" conjoined to the text such substring selections can be made without copying the text to a work area, unlike the `copy(text,start,stop)` equivalent of Pascal for example. Some Fortran compilers do offer a starting point, and also an option to search backwards from the end, but these facilities are not guaranteed. Similarly, INDEX is only made available for CHARACTER searching, even though it could easily be generalised to other types.

A second problem is presented by the possibility that a logical expression such as `L.LT.0 .OR. etc.` will always or might possibly or in certain constructions but not others be fully evaluated, which is to say that the etc will be evaluated even though L < 0 is true so that the result is determined. And in this case, evaluating the etc will cause trouble because the indexing won't work! To be safe, therefore, a rather lame two-stage test is required - though optimising compilers might well shift code around anyway.

In the case of STARTS, these annoyances can be left to the INDEX function rather than comparing the start of A against B. At the cost of it searching the whole of A if B is not at the start. Otherwise, it would be the mirror of ENDS.

`       SUBROUTINE STARTS(A,B)	!Text A starts with text B?       CHARACTER*(*) A,B        IF (INDEX(A,B).EQ.1) THEN	!Searches A to find B.          WRITE (6,*) ">",A,"< starts with >",B,"<"         ELSE          WRITE (6,*) ">",A,"< does not start with >",B,"<"        END IF      END SUBROUTINE STARTS       SUBROUTINE HAS(A,B)	!Text B appears somewhere in text A?       CHARACTER*(*) A,B       INTEGER L        L = INDEX(A,B)		!The first position in A where B matches.        IF (L.LE.0) THEN          WRITE (6,*) ">",A,"< does not contain >",B,"<"         ELSE          WRITE (6,*) ">",A,"< contains a >",B,"<, offset",L        END IF      END SUBROUTINE HAS       SUBROUTINE ENDS(A,B)	!Text A ends with text B.       CHARACTER*(*) A,B       INTEGER L        L = LEN(A) - LEN(B)	!Find the tail end of A that B might match.        IF (L.LT.0) THEN	!Dare not use an OR, because of full evaluation risks.          WRITE (6,*) ">",A,"< is too short to end with >",B,"<"	!Might as well have a special message.        ELSE IF (A(L + 1:L + LEN(B)).NE.B) THEN	!Otherwise, it is safe to look.          WRITE (6,*) ">",A,"< does not end with >",B,"<"        ELSE          WRITE (6,*) ">",A,"< ends with >",B,"<"        END IF      END SUBROUTINE ENDS       CALL STARTS("This","is")      CALL STARTS("Theory","The")      CALL HAS("Bananas","an")      CALL ENDS("Banana","an")      CALL ENDS("Banana","na")      CALL ENDS("Brief","Much longer")      END `

Output: text strings are bounded by >etc.< in case of leading or trailing spaces.

``` >This< does not start with >is<
>Theory< starts with >The<
>Bananas< contains a >an<, offset           2
>Banana< does not end with >an<
>Banana< ends with >na<
>Brief< is too short to end with >Much longer<
```

Similar program using modern Fortran style

` !-----------------------------------------------------------------------!Main program string_matching!-----------------------------------------------------------------------program    string_matching   implicit none   character(len=*), parameter :: fmt= '(I0)'   write(*,fmt) starts("this","is")   write(*,fmt) starts("theory","the")   write(*,fmt) has("bananas","an")   write(*,fmt) ends("banana","an")   write(*,fmt) ends("banana","na")   write(*,fmt) ends("brief","much longer")  contains   !     Determining if the first string starts with second string   function  starts(string1, string2) result(answer)      implicit none      character(len=*), intent(in) :: string1      character(len=*), intent(in) :: string2      integer :: answer      answer = 0      if(len(string2)>len(string1)) return      if(string1(1:len(string2))==string2) answer = 1   end function starts   !     Determining if the first string contains the second string at any location   function  has(string1, string2) result(answer)      implicit none      character(len=*), intent(in) :: string1      character(len=*), intent(in) :: string2      character(len=:),allocatable :: temp      integer :: answer, add      character(len=*), parameter :: fmt= '(A6,X,I0)'      answer = 0      add = 0      if(len(string2)>len(string1)) return      answer = index(string1, string2)      if(answer==0) return      !     Print the location of the match for part 2      write(*,fmt) " at ", answer      !     Handle multiple occurrences of a string for part 2.      add = answer      temp = string1(answer+1:)      do while(answer>0)         answer = index(temp, string2)         add = add + answer         if(answer>0) write(*,fmt) " at ", add         !          deallocate(temp)         temp = string1(add+1:) ! auto reallocation      enddo      answer = 1   end function has   !     Determining if the first string ends with the second string   function  ends(string1, string2) result(answer)      implicit none      character(len=*), intent(in) :: string1      character(len=*), intent(in) :: string2      integer :: answer      answer = 0      if(len(string2)>len(string1)) return      if(string1(len(string1)-len(string2)+1:)==string2) answer = 1   end function endsend program string_matching `

Output: false = 0, true = 1 ( + multiple occurrences if applicable)

```0
1
at  2
at  4
1
0
1
0
```

In recent standards of Fortran strings as intrinsic first-class type and many intrinsic procedures for strings manipulation have been added.

FreeBASIC

`' FB 1.05.0 Win64 Dim As String s1 = "abracadabra"Dim As String s2 = "abra"Print "First string  : "; s1Print "Second string : "; s2PrintPrint "First string begins with second string : "; CBool(s2 = Left(s1, Len(s2))) Dim As Integer i1 = Instr(s1, s2)Dim As Integer i2 Print "First string contains second string    : ";If i1 Then   Print "at index"; i1;  i2 = Instr(i1 + Len(s2), s1, s2)  If i2 Then    Print " and at index"; i2  Else    Print  End IfElse  Print "false";End IfPrint "First string ends with second string   : "; CBool(s2 = Right(s1, Len(s2)))PrintPrint "Press any key to quit"Sleep`
Output:
```First string  : abracadabra
Second string : abra

First string begins with second string : true
First string contains second string    : at index 1 and at index 8
First string ends with second string   : true
```

Gambas

`Public Sub Main()Dim sString1 As String = "Hello world"Dim sString2 As String = "Hello" Print sString1 Begins Left(sString2, 5)                             'Determine if the first string starts with second stringIf InStr(sString1, sString2) Then Print "True" Else Print "False"   'Determine if the first string contains the second string at any locationPrint sString1 Ends Left(sString2, 5)                               'Determine if the first string ends with the second string End`

Output:

```True
True
False
```

GML

Translation of: BASIC
`#define charMatch{    first = "qwertyuiop";     // Determining if the first string starts with second string     second = "qwerty";    if (string_pos(second, first) > 0) {        show_message("'" + first + "' starts with '" + second + "'");    } else {        show_message("'" + first + "' does not start with '" + second + "'");    }     second = "wert"    // Determining if the first string contains the second string at any location    // Print the location of the match for part 2    if (string_pos(second, first) > 0) {        show_message("'" + first + "' contains '" + second + "' at position " + string(x));    } else {        show_message("'" + first + "' does not contain '" + second + "'");    }    // Handle multiple occurrences of a string for part 2.    x = string_count(second, first);    show_message("'" + first + "' contains " + string(x) + " instances of '" + second + "'"); // Determining if the first string ends with the second string    second = "random garbage"    temp = string_copy(first,                       (string_length(first) - string_length(second)) + 1,                        string_length(second));    if (temp == second) {        show_message("'" + first + "' ends with '" + second + "'");    } else {        show_message("'" + first + "' does not end with '" + second + "'");    }}`
Output:
(in message boxes, 1 per line):
```'qwertyuiop' starts with 'qwerty'
'qwertyuiop' contains 'wert' at position 0
'qwertyuiop' contains 1 instances of 'wert'
'qwertyuiop' does not end with 'random garbage'
```

Go

`package main import (    "fmt"    "strings") func match(first, second string) {    fmt.Printf("1. %s starts with %s: %t\n",        first, second, strings.HasPrefix(first, second))    i := strings.Index(first, second)    fmt.Printf("2. %s contains %s: %t,\n", first, second, i >= 0)    if i >= 0 {        fmt.Printf("2.1. at location %d,\n", i)        for start := i+1;; {            if i = strings.Index(first[start:], second); i < 0 {                break            }            fmt.Printf("2.2. at location %d,\n", start+i)            start += i+1        }        fmt.Println("2.2. and that's all")    }    fmt.Printf("3. %s ends with %s: %t\n",        first, second, strings.HasSuffix(first, second))} func main() {    match("abracadabra", "abr")}`
Output:
```1. abracadabra starts with abr: true
2.1. at location 0,
2.2. at location 7,
2.2. and that's all
3. abracadabra ends with abr: false
```

Groovy

Examples:

`assert "abcd".startsWith("ab")assert ! "abcd".startsWith("zn")assert "abcd".endsWith("cd")assert ! "abcd".endsWith("zn")assert "abab".contains("ba")assert ! "abab".contains("bb")  assert "abab".indexOf("bb") == -1 // not found flagassert "abab".indexOf("ab") == 0 def indicesOf = { string, substring ->    if (!string) { return [] }    def indices = [-1]    while (true) {        indices << string.indexOf(substring, indices.last()+1)        if (indices.last() == -1) break    }    indices[1..<(indices.size()-1)]}assert indicesOf("abab", "ab") == [0, 2]assert indicesOf("abab", "ba") == [1]assert indicesOf("abab", "xy") == []`

All assertions pass, so there is no output.

`> import Data.List> "abc" `isPrefixOf` "abcdefg"True> "efg" `isSuffixOf` "abcdefg"True> "bcd" `isInfixOf` "abcdefg"True> "abc" `isInfixOf` "abcdefg" -- Prefixes and suffixes are also infixesTrue> let infixes a b = findIndices (isPrefixOf a) \$ tails b> infixes "ab" "abcdefabqqab"[0,6,10]`

Icon and Unicon

`procedure main()    write("Matching s2 :=",image(s2 := "ab")," within s1:= ",image(s1 := "abcdabab"))    write("Test #1 beginning ",if match(s2,s1) then "matches " else "failed")   writes("Test #2 all matches at positions [")       every writes(" ",find(s2,s1)|"]\n")   write("Test #3 ending ", if s1[0-:*s2] == s2 then "matches" else "fails") end`
Output:
```Matching s2 :="ab" within s1:= "abcdabab"
Test #1 beginning matches
Test #2 all matches at positions [ 1 5 7 ]
Test #3 ending matches```

J

`startswith=: ] -: ({.~ #)contains=: +./@:E.~endswith=: ] -: ({.~ [email protected]#)`

Example use:

`   'abcd' startswith 'ab'1   'abcd' startswith 'cd'0   'abcd' endswith 'ab'0   'abcd' endswith 'cd'1   'abcd' contains 'bb'0   'abcd' contains 'ab'1   'abcd' contains 'bc'1   'abab' contains 'ab'1   'abab' [email protected]~ 'ab'       NB. find starting indicies0 2`

Note that these verbs contain no constraints restricting them to sequences of characters and so also apply to arrays of type other than character:

`   0 1 2 3 startswith 0 1               NB. integer1   4.2 5.1 1.3 9 3 contains 1.3 4.2     NB. floating point0   4.2 5.1 1.3 4.2 9 3 contains 1.3 4.2 1`

Java

`"abcd".startsWith("ab") //returns true"abcd".endsWith("zn") //returns false"abab".contains("bb") //returns false"abab".contains("ab") //returns trueint loc = "abab".indexOf("bb") //returns -1loc = "abab".indexOf("ab") //returns 0loc = "abab".indexOf("ab",loc+1) //returns 2`

// -----------------------------------------------------------// public class JavaApplication6 {

```   public static void main(String[] args) {
String strOne = "complexity";
String strTwo = "udacity";
```
```       //
stringMatch(strOne, strTwo);
```
```   }
```
```   public static void stringMatch(String one, String two) {
boolean match = false;
if (one.charAt(0) == two.charAt(0)) {
System.out.println(match = true);   // returns true
} else {
System.out.println(match);       // returns false
}
for (int i = 0; i < two.length(); i++) {
int temp = i;
for (int x = 0; x < one.length(); x++) {
if (two.charAt(temp) == one.charAt(x)) {
System.out.println(match = true);    //returns true
i = two.length();
}
}
}
int num1 = one.length() - 1;
int num2 = two.length() - 1;
if (one.charAt(num1) == two.charAt(num2)) {
System.out.println(match = true);
} else {
System.out.println(match = false);
}
}
```

}

JavaScript

`var stringA = "tacoloco"  , stringB = "co"  , q1, q2, q2multi, m  , q2matches = [] // stringA starts with stringBq1 = stringA.substring(0, stringB.length) == stringB // stringA contains stringBq2  = stringA.indexOf(stringB) // multiple matchesq2multi = new RegExp(stringB,'g') while(m = q2multi.exec(stringA)){	q2matches.push(m.index)} // stringA ends with stringBq3 = stringA.substr(-stringB.length) == stringB console.log("1: Does '"+stringA+"' start with '"+stringB+"'? " + ( q1 ? "Yes." : "No."))console.log("2: Is '"+stringB+"' contained in '"+stringA+"'? " + (~q2 ? "Yes, at index "+q2+"." : "No."))if (~q2 && q2matches.length > 1){	console.log("   In fact, it happens "+q2matches.length+" times within '"+stringA+"', at index"+(q2matches.length > 1 ? "es" : "")+" "+q2matches.join(', ')+".")}console.log("3: Does '"+stringA+"' end with '"+stringB+"'? "   + ( q3 ? "Yes." : "No."))`
Output:
```1: Does 'tacoloco' start with 'co'? No.
2: Is 'co' contained in 'tacoloco'? Yes, at index 2.
In fact, it happens 2 times within 'tacoloco', at indexes 2, 6.
3: Does 'tacoloco' end with 'co'? Yes.```

Lasso

`local( a = 'a quick brown peanut jumped over a quick brown fox', b = 'a quick brown') //Determining if the first string starts with second string#a->beginswith(#b) // true //Determining if the first string contains the second string at any location#a >> #b           // true#a->contains(#b)   // true //Determining if the first string ends with the second string#a->endswith(#b)   // false`

jq

Using the builtins of jq 1.4 and later:

`# startswith/1 is boolean:"abc" | startswith("ab")#=> true`
`# index/1 returns the index or null, # so the jq test "if index(_) then ...." can be used# without any type conversion. "abcd" | index( "bc")#=> 1`
`# endswith/1 is also boolean:"abc" | endswith("bc")#=> true`

Using the regex functions available in jq 1.5:

`"abc" | test( "^ab") "abcd" | test("bc") "abcd" | test("cd\$")`

Multiple Occurrences

To determine all the indices of one string in another:

`# In jq 1.4 or later:jq -n '"abcdabcd" | indices("bc")'[  1,  5]`

In jq 1.5, the regex function match/1 can also be used:

`\$ jq -n '"abcdabcd" | match("bc"; "g") | .offset'15`

Julia

`startswith("abcd","ab") #returns truesearch("abcd","ab") #returns 1:2, indices range where string was foundendswith("abcd","zn") #returns falseismatch(r"ab","abcd") #returns true where 1st arg is regex stringjulia>for r in each_match(r"ab","abab")	println(r.offset)end13`

K

`startswith: {:[0<#p:_ss[x;y];~*p;0]}endswith: {0=(-#y)+(#x)-*_ss[x;y]}contains: {0<#_ss[x;y]}`

Example:

`  startswith["abcd";"ab"]1  startswith["abcd";"bc"]0  endswith["abcd";"cd"]1  endswith["abcd";"bc"]0  contains["abcdef";"cde"]1  contains["abcdef";"bdef"]0  _ss["abcdabceabc";"abc"]    / location of matches0 4 8`

Kotlin

`// version 1.0.6 fun main(args: Array<String>) {    val s1 = "abracadabra"    val s2 = "abra"        println("\$s1 begins with \$s2 : \${s1.startsWith(s2)}")    println("\$s1 ends with \$s2   : \${s1.endsWith(s2)}")    val b  = s2 in s1    print("\$s1 contains \$s2    : \$b")    if (b) println(" at locations \${s1.indexOf(s2) + 1} and \${s1.lastIndexOf(s2) + 1}")    else println()}`
Output:
```abracadabra begins with abra : true
abracadabra ends with abra   : true
abracadabra contains abra    : true at locations 1 and 8
```

LabVIEW

These images solve the task's requirements in order.
This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.

Lang5

`: 2array  2 compress ; : bi*  '_ set dip _ execute ;  : [email protected]  dup bi* ;: comb  "" split ;  : concat  "" join ;  : dip  swap '_ set execute _ ;: first  0 extract swap drop ; : flip  comb reverse concat ; : contains    swap 'comb [email protected] length do                    # create a matrix.         1 - "dup 1 1 compress rotate" dip dup 0 == if break then    loop drop length compress swap drop    "length 1 -" [email protected] rot 0 0 "'2array dip" '2array bi* swap 2array slice reverse    : concat.(*)  concat ;    'concat "'concat. apply" bi* eq 1 1 compress index collapse    length if expand drop else drop 0 then ;    # r: position.: end-with    'flip [email protected] start-with ;: start-with  'comb [email protected] length rot swap iota subscript 'concat [email protected] eq ; "rosettacode" "rosetta" start-with .    # 1"rosettacode" "taco" contains .         # 5"rosettacode" "ocat" contains .         # 0"rosettacode" "edoc" end-with .         # 0"rosettacode" "code" contains .         # 7`

Liberty BASIC

`'1---Determining if the first string starts with second stringst1\$="first string"st2\$="first"if left\$(st1\$,len(st2\$))=st2\$ then    print "First string starts with second string."end if '2---Determining if the first string contains the second string at any location'2.1---Print the location of the match for part 2st1\$="Mississippi"st2\$="i"if instr(st1\$,st2\$) then    print "First string contains second string."    print "Second string is at location ";instr(st1\$,st2\$)end if '2.2---Handle multiple occurrences of a string for part 2.pos=instr(st1\$,st2\$)while pos    count=count+1    pos=instr(st1\$,st2\$,pos+len(st2\$))wendprint "Number of times second string appears in first string is ";count '3---Determining if the first string ends with the second stringst1\$="first string"st2\$="string"if right\$(st1\$,len(st2\$))=st2\$ then    print "First string ends with second string."end if `

Lingo

`a = "Hello world!"b = "Hello" -- Determining if the first string starts with second stringput a starts b-- 1 -- Determining if the first string contains the second string at any locationput a contains b-- 1 -- Determining if the first string ends with the second stringput a.char[a.length-b.length+1..a.length] = b-- 0 b = "world!"put a.char[a.length-b.length+1..a.length] = b-- 1 -- Print the location of the match for part 2put offset(b, a)-- 7`

Logo

`to starts.with? :sub :thing  if empty? :sub [output "true]  if empty? :thing [output "false]  if not equal? first :sub first :thing [output "false]  output starts.with? butfirst :sub butfirst :thingend to ends.with? :sub :thing  if empty? :sub [output "true]  if empty? :thing [output "false]  if not equal? last :sub last :thing [output "false]  output ends.with? butlast :sub butlast :thingend show starts.with? "dog "doghouse    ; trueshow ends.with? "house "doghouse    ; trueshow substring? "gho "doghouse       ; true  (built-in)`

Lua

`s1 = "string"s2 = "str"s3 = "ing"s4 = "xyz" print( "s1 starts with s2: ", string.find( s1, s2 ) == 1 )print( "s1 starts with s3: ", string.find( s1, s3 ) == 1, "\n" ) print( "s1 contains s3: ", string.find( s1, s3 ) ~= nil )print( "s1 contains s3: ", string.find( s1, s4 ) ~= nil, "\n" )    print( "s1 ends with s2: ", select( 2, string.find( s1, s2 ) ) == string.len( s1 ) )print( "s1 ends with s3: ", select( 2, string.find( s1, s3 ) ) == string.len( s1 ) )`

M2000 Interpreter

` Module StringMatch {      A\$="Hello World"      Print A\$ ~ "Hello*"      Print A\$ ~ "*llo*"      p=Instr(A\$, "llo")      Print p=3      \\ Handle multiple occurance for "o"      p=Instr(A\$, "o")      While p > 0 {            Print "position:";p;{ for "o"}            p=Instr(A\$, "o", p+1)      }      Print A\$ ~ "*orld"}{{out}}<pre>    True    True    Trueposition:5 for "o"position:8 for "o"    True</pre>StringMatch `

Maple

These facilities are all to be found in the StringTools package in Maple.

` > with( StringTools ): # bind package exports at the top-level> s := "dzrIemaWWIMidXYZwGiqkOOn":> s[1..4]; # pick a prefix                                 "dzrI" > IsPrefix( s[ 1 .. 4 ], s ); # check it                                  true > s[ -4 .. -1 ]; # pick a suffix                                 "kOOn" > IsSuffix( s[ -4 .. -1 ], s ); # check it                                  true > p := Search( "XYZ", s ); # find a substring                                p := 14 > s[ p .. p + 2 ]; # check                                 "XYZ" > SearchAll( [ "WWI", "XYZ" ], s ); # search for multiple patterns                            [8, 1], [14, 2] > to 3 do s := cat( s, s ) end: length( s ); # build a longer string by repeated doubling                                  192 > p := SearchAll( "XYZ", s ); # find all occurrences                p := 14, 38, 62, 86, 110, 134, 158, 182 > {seq}( s[ i .. i + 2 ], i = p ); # check them                                {"XYZ"} `

The StringTools package also contains facilities for regular expression matching, but for fixed string patterns, the Search and SearchAll tools are much faster.

Mathematica

`StartWith[x_, y_] := MemberQ[Flatten[StringPosition[x, y]], 1]EndWith[x_, y_] :=  MemberQ[Flatten[StringPosition[x, y]], StringLength[x]]StartWith["XYZaaabXYZaaaaXYZXYZ", "XYZ"]EndWith["XYZaaabXYZaaaaXYZXYZ", "XYZ"]StringPosition["XYZaaabXYZaaaaXYZXYZ", "XYZ"]`
Output:
```True
True
{{1,3},{8,10},{15,17},{18,20}}```

MATLAB / Octave

`    % 1. Determining if the first string starts with second string	strcmp(str1,str2,length(str2))   % 2. Determining if the first string contains the second string at any location	~isempty(strfind(s1,s2))   % 3. Determining if the first string ends with the second string 	( (length(str1)>=length(str2)) && strcmp(str1(end+[1-length(str2):0]),str2) )    % 1. Print the location of the match for part 2	disp(strfind(s1,s2))   % 2. Handle multiple occurrences of a string for part 2. 	ix = strfind(s1,s2);   % ix is a vector containing the starting positions of s2 within s1 `

NetRexx

`/* NetRexx */options replace format comments java crossref savelog symbols lipsum = ''x_ = 0x_ = x_ + 1; lipsum[0] = x_; lipsum[x_] = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'x_ = x_ + 1; lipsum[0] = x_; lipsum[x_] = lipsum[1].reverse srch = ''srch[1] = 'Lorem ipsum dolor sit amet'srch[2] = 'consectetur adipisicing elit'srch[3] = 'dolore magna aliqua.' loop j_ = 1 to lipsum[0]  x1 = lipsum[j_].pos(srch[1])  x2 = lipsum[j_].pos(srch[2])  x3 = lipsum[j_].lastpos(srch[3])   report(x1 = 1, lipsum[j_], srch[1], 'Test string starts with search string:', 'Test string does not start with search string:')  report(x2 > 0, lipsum[j_], srch[2], 'Search string located in test string at position:' x2,  'Search string not found within test string:')  report(x3 \= srch[3].length, lipsum[j_], srch[3], 'Test string ends with search string:', 'Test string does not start with search string:')  end j_ many = ''x_ = 0x_ = x_ + 1; many[0] = x_; many[x_] = 'How many times does "many times" occur in this string?'x_ = x_ + 1; many[0] = x_; many[x_] = 'How often does "many times" occur in this string?'x_ = x_ + 1; many[0] = x_; many[x_] = 'How often does it occur in this string?'srch[4] = 'many times' loop j_ = 1 to many[0]  o_ = 0  k_ = 0  loop label dups until o_ = 0    o_ = many[j_].pos(srch[4], o_ + 1)    if o_ \= 0 then k_ = k_ + 1    end dups  report(k_ > 0, many[j_], srch[4], 'Number of times search string occurs:' k_, 'Search string not found')  end j_ method report(state = boolean, ts, ss, testSuccess, testFailure) public static  if state then say testSuccess  else          say testFailure  say '    Test string:' ts  say '  Search string:' ss  say   return `

NewLISP

`(setq str "abcdefbcghi") ;; test if str starts with "ab"(starts-with str "ab") ;; find "bc" inside str(find "bc" str) ;; test if str ends with "ghi"(ends-with str "ghi") ;; find all positions of pattern inside str(define (find-all-pos pattern str)  (let ((idx -1) (pos '()))    (while (setq idx (find pattern str 0 (+ idx 1)))      (push idx pos -1)))) (find-all-pos "bc" str)`

Nim

`import strutils var s: string = "The quick brown fox"if startsWith(s, "The quick"):   echo("Starts with: The quick")if endsWith(s, "brown Fox"):   echo("Ends with: brown fox")var pos = find(s, " brown ")  # -1 if not foundif contains(s, " brown "):    # showing the contains() proc, but could use if pos!=-1:   echo('"' & " brown " & '"' & " is located at position: " & \$pos)`
Output:
```Starts with: The quick
Ends with: brown fox
" brown " is located at position: 9```

Objective-C

`[@"abcd" hasPrefix:@"ab"] //returns true[@"abcd" hasSuffix:@"zn"] //returns falseint loc = [@"abab" rangeOfString:@"bb"].location //returns -1loc = [@"abab" rangeOfString:@"ab"].location //returns 0loc = [@"abab" rangeOfString:@"ab" options:0 range:NSMakeRange(loc+1, [@"abab" length]-(loc+1))].location //returns 2`

Objeck

` bundle Default {  class Matching {    function : Main(args : System.String[]) ~ Nil {      "abcd"->StartsWith("ab")->PrintLine(); # returns true      "abcd"->EndsWith("zn")->PrintLine(); # returns false      ("abab"->Find("bb") <> -1)->PrintLine(); # returns false      ("abab"->Find("ab") <> -1)->PrintLine(); # returns true      loc := "abab"->Find("bb"); # returns -1      loc := "abab"->Find("ab"); # returns 0      loc := "abab"->Find("ab", loc + 1); # returns 2    }  }} `

OCaml

`let match1 s1 s2 =  let len1 = String.length s1  and len2 = String.length s2 in  if len1 < len2 then false else    let sub = String.sub s1 0 len2 in    (sub = s2)`

testing in the top-level:

```# match1 "Hello" "Hello World!" ;;
- : bool = false
# match1 "Hello World!" "Hello" ;;
- : bool = true
```
`let match2 s1 s2 =  let len1 = String.length s1  and len2 = String.length s2 in  if len1 < len2 then false else    let rec aux i =      if i < 0 then false else        let sub = String.sub s1 i len2 in        if (sub = s2) then true else aux (pred i)    in    aux (len1 - len2)`
```# match2 "It's raining, Hello World!" "umbrella" ;;
- : bool = false
# match2 "It's raining, Hello World!" "Hello" ;;
- : bool = true
```
`let match3 s1 s2 =  let len1 = String.length s1  and len2 = String.length s2 in  if len1 < len2 then false else    let sub = String.sub s1 (len1 - len2) len2 in    (sub = s2)`
```# match3 "Hello World" "Hello" ;;
- : bool = false
# match3 "Hello World" "World" ;;
- : bool = true
```
`let match2_loc s1 s2 =  let len1 = String.length s1  and len2 = String.length s2 in  if len1 < len2 then (false, -1) else    let rec aux i =      if i < 0 then (false, -1) else        let sub = String.sub s1 i len2 in        if (sub = s2) then (true, i) else aux (pred i)    in    aux (len1 - len2)`
```# match2_loc "The sun's shining, Hello World!" "raining" ;;
- : bool * int = (false, -1)
# match2_loc "The sun's shining, Hello World!" "shining" ;;
- : bool * int = (true, 10)
```
`let match2_num s1 s2 =  let len1 = String.length s1  and len2 = String.length s2 in  if len1 < len2 then (false, 0) else    let rec aux i n =      if i < 0 then (n <> 0, n) else        let sub = String.sub s1 i len2 in        if (sub = s2)        then aux (pred i) (succ n)        else aux (pred i) (n)    in    aux (len1 - len2) 0`
```# match2_num "This cloud looks like a camel, \
that other cloud looks like a llama" "stone" ;;
- : bool * int = (false, 0)
# match2_num "This cloud looks like a camel, \
that other cloud looks like a llama" "cloud" ;;
- : bool * int = (true, 2)
```

Oforth

`: stringMatching(s1, s2)| i |   s2 isAllAt(s1, 1) ifTrue: [ System.Out s1 << " begins with " << s2 << cr ]   s2 isAllAt(s1, s1 size s2 size - 1 + ) ifTrue: [ System.Out s1 << " ends with " << s2 << cr ]     s1 indexOfAll(s2) ->i   i ifNotNull: [ System.Out s1 << " includes " << s2 << " at position : " << i << cr ]    "\nAll positions : " println    1 ->i   while (s1 indexOfAllFrom(s2, i) dup ->i notNull) [      System.Out s1 << " includes " << s2 << " at position : " << i << cr      i s2 size + ->i      ] ;`
Output:
```> "arduinoardblobard", "ard" stringMatching
arduinoardblobard begins with ard
arduinoardblobard ends with ard
arduinoardblobard includes ard at position : 1

All positions :
arduinoardblobard includes ard at position : 1
arduinoardblobard includes ard at position : 8
arduinoardblobard includes ard at position : 15
```

OxygenBasic

` string s="sdfkjhgsdfkdfgkbopefioqwurti487sdfkrglkjfs9wrtgjglsdfkdkjcnmmb.,msfjflkjsdfk" string f="sdfk" string cr=chr(13)+chr(10),tab=chr(9) string pr="FIND STRING LOCATIONS" cr cr sys a=0, b=1, count=0, ls=len(s), lf=len(f) do  a=instr b,s,f  if a=0 then exit do  count++  if a=1 then  pr+="Begins with keyword" cr  pr+=count tab a cr  if a=ls-lf+1 then pr+="Ends with keyword at " a cr  b=a+1end do pr+=cr "Total matches: " count cr print pr 'FIND STRING LOCATIONS''Begins with keyword'1	1'2	8'3	32'4	51'5	73'Ends with keyword at 73''Total matches: 5 `

PARI/GP

This meets the first but not the second of the optional requirements. Note that GP treats any nonzero value as true so the location found by contains() can be ignore if not needed.

`startsWith(string, prefix)={  string=Vec(string);  prefix=Vec(prefix);  if(#prefix > #string, return(0));  for(i=1,#prefix,if(prefix[i]!=string[i], return(0)));  1};contains(string, inner)={  my(good);  string=Vec(string);  inner=Vec(inner);  for(i=0,#string-#inner,    good=1;    for(j=1,#inner,      if(inner[j]!=string[i+j], good=0; break)    );    if(good, return(i+1))  );  0};endsWith(string, suffix)={  string=Vec(string);  suffix=Vec(suffix);  if(#suffix > #string, return(0));  for(i=1,#suffix,if(prefix[i]!=string[i+#string-#suffix], return(0)));  1};`

Perl

Using regexes:

`\$str1 =~ /^\Q\$str2\E/  # true if \$str1 starts with \$str2\$str1 =~ /\Q\$str2\E/   # true if \$str1 contains \$str2\$str1 =~ /\Q\$str2\E\$/  # true if \$str1 ends with \$str2`

Using `index`:

`index(\$str1, \$str2) == 0                               # true if \$str1 starts with \$str2index(\$str1, \$str2) != -1                              # true if \$str1 contains \$str2rindex(\$str1, \$str2) == length(\$str1) - length(\$str2)  # true if \$str1 ends with \$str2`

Using `substr`:

`substr(\$str1, 0, length(\$str2)) eq \$str2  # true if \$str1 starts with \$str2substr(\$str1, - length(\$str2)) eq \$str2   # true if \$str1 ends with \$str2`

Bonus task (printing all positions where `\$str2` appears in `\$str1`):

`print \$-[0], "\n" while \$str1 =~ /\Q\$str2\E/g;  # using a regex`
`my \$i = -1; print \$i, "\n" while (\$i = index \$str1, \$str2, \$i + 1) != -1;  # using index`

Perl 6

Using string methods:

`\$haystack.starts-with(\$needle)  # True if \$haystack starts with \$needle\$haystack.contains(\$needle)     # True if \$haystack contains \$needle\$haystack.ends-with(\$needle)    # True if \$haystack ends with \$needle`

Using regexes:

`so \$haystack ~~ /^ \$needle  /  # True if \$haystack starts with \$needleso \$haystack ~~ /  \$needle  /  # True if \$haystack contains \$needleso \$haystack ~~ /  \$needle \$/  # True if \$haystack ends with \$needle`

Using `substr`:

`substr(\$haystack, 0, \$needle.chars) eq \$needle  # True if \$haystack starts with \$needlesubstr(\$haystack, *-\$needle.chars) eq \$needle   # True if \$haystack ends with \$needle`

`\$haystack.match(\$needle, :g)».from;  # List of all positions where \$needle appears in \$haystack`

Phix

`constant word = "the",                                      -- (also try this with "th"/"he")         sentence = "the last thing the man said was the"--       sentence = "thelastthingthemansaidwasthe"          -- (practically the same results) -- A common, but potentially inefficient idiom for checking for a substring at the start is:if match(word,sentence)=1 then    ?"yes(1)"end if-- A more efficient method is to test the appropriate sliceif length(sentence)>=length(word) and sentence[1..length(word)]=word then    ?"yes(2)"end if-- Which is almost identical to checking for a word at the endif length(sentence)>=length(word) and sentence[-length(word)..-1]=word then    ?"yes(3)"end if-- Or sometimes you will see this, a tiny bit more efficient:if length(sentence)>=length(word)and match(word,sentence,length(sentence)-length(word)+1) then    ?"yes(4)"end if-- Finding all occurences is a snap:integer r = match(word,sentence)while r!=0 do    ?r    r = match(word,sentence,r+1)end while`
Output:
```"yes(1)"
"yes(2)"
"yes(3)"
"yes(4)"
1
16
33
```

PHP

`<?php/*********************************************************************************** This program gets needle and haystack from the caller (chm.html) (see below)* and checks for occurrences of the needle in the haystack* 02.05.2013 Walter Pachl* Comments or Suggestions welcome**********************************************************************************/\$haystack = \$_POST['haystack']; if (\$haystack=='') {\$haystack='no haystack given';}\$needle   = \$_POST['needle'];   if (\$needle=='')   {\$needle='no needle given';} function rexxpos(\$h,\$n) {  \$pos = strpos(\$h,\$n);  if (\$pos === false) { \$pos=-1; }  else                { \$pos=\$pos+1; }  return (\$pos); } \$pos=rexxpos(\$haystack,\$needle);\$tx1 = "";if (\$pos==-1){ \$n=0; }  // not foundelse         { \$n=1; }  // found once (so far)// Special casesif (\$pos==1){ \$tx1="needle found to be the start of the haystack"; }if (\$pos==strlen(\$haystack)-strlen(\$needle)+1)            { \$tx1="needle found at end of haystack"; } if (\$n>0) { // look for other occurrences  \$pl=\$pos; // list of positions  \$p=\$pos;  //  \$x="*************************************";  \$h=\$haystack;  while (\$p>0) {    \$h=substr(\$x,0,\$p).substr(\$h,\$p);    \$p=rexxpos(\$h,\$needle);    if ( \$p>0 ) { \$n=\$n+1; \$pl=\$pl.",&nbsp;".\$p; }  }       if (\$n==1) { \$txt="needle found once in haystack, position: \$pl."; }  else if (\$n==2) { \$txt="needle found twice in haystack, position(s): \$pl."; }  else            { \$txt="needle found \$n times in haystack, position(s): \$pl."; }}else              { \$txt="needle not found in haystack."; }?><html>  <head>    <title>Character Matching</title>    <meta name="author" content="Walter Pachl">    <meta name="date" content="02.05.2013">    <style>      p { font: 120% courier; }    </style>  </head>  <body>    <p><strong>Haystack:&nbsp;'<?php echo "\$haystack" ?>'</strong></p>    <p><strong>Needle:&nbsp;&nbsp;&nbsp;'<?php echo "\$needle" ?>'</strong></p>    <p><strong><?php echo "\$txt" ?></strong></p>    <!-- special message: -->    <p  style="color: red";><strong><?php echo "\$tx1" ?></strong></p>  </body></html>`
`<?php<!DOCTYPE html><!--/************************************************************************* Here we prompt the user for a haystack and a needle* We then invoke program chmx.php* to check for occurrences of the needle in the haystack* 02.05.2013 Walter Pachl* Comments or Suggestions welcome************************************************************************/--><html>  <head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />    <title>Character matching</title>  </head>  <body>    <form id="test" name="test" method="post" action="chmx.php">    <h1>Character matching</h1>    <p>Given two strings, demonstrate the following 3 types of matchings:    <ol style="margin-top:2; margin-bottom:2;">    <li>Determining if the first string starts with second string    <li>Determining if the first string contains the second string at any location    <li>Determining if the first string ends with the second string    </ol>    <p>Optional requirements:    <ol style="margin-top:2; margin-bottom:2;">    <li>Print the location of the match(es) for part 2    <li>Handle multiple occurrences of a string for part 2.    </ol>    <p style="margin-top:5; margin-bottom:3;">       <font face="Courier"><strong>Haystack:</strong>       <strong><input type="text" name="haystack" size="80"></strong></font></p>    <p style="margin-top:5; margin-bottom:3;">       <font face="Courier"><strong>Needle:&nbsp;&nbsp;</strong>       <strong><input type="text" name="needle" size="80"></strong></font></p>    <p>Press <input name="Submit" type="submit" class="erfolg" value="CHECK"/>       to invoke chmx.php.</p>  </form>  </body></html>`

PicoLisp

`: (pre? "ab" "abcd")-> "abcd": (pre? "xy" "abcd")-> NIL : (sub? "bc" "abcd")-> "abcd": (sub? "xy" "abcd")-> NIL : (tail (chop "cd") (chop "abcd"))-> ("c" "d"): (tail (chop "xy") (chop "abcd"))-> NIL  (de positions (Pat Str)   (setq Pat (chop Pat))   (make      (for ((I . L) (chop Str) L (cdr L))         (and (head Pat L) (link I)) ) ) ) : (positions "bc" "abcdabcd")-> (2 6)`

PL/I

` /*  Let s be one string, t be the other that might exist within s. */                                                     /* 8-1-2011 */k = index(s, t);if k = 0 then put skip edit (t, ' is nowhere in sight') (a);else if k = 1 then   put skip edit (t, '  starts at the beginning of  ', s) (a);else if k+length(t)-1 = length(s) then   put skip edit (t, '  is at the end of  ', s) (a);else put skip edit (t, '  is within  ', s) (a); if k > 0 then put skip edit (t, '  starts at position  ', k) (a); `

Optional extra:

` /* Handle multiple occurrences. */   n = 1;   do forever;      k = index(s, t, n);      if k = 0 then         do;            if n = 1 then put skip list (t, ' is nowhere in sight');            stop;         end;      else if k = 1 then         put skip edit ('<', t, '> starts at the beginning of  ', s) (a);      else if k+length(t)-1 = length(s) then         put skip edit ('<', t, '> is at the end of  ', s) (a);      else put skip edit ('<', t, '> is within  ', s) (a);      n =   k + length(t);       if k > 0 then         put skip edit ('<', t, '> starts at position ', trim(k)) (a);      else stop;   end; `

PureBasic

`Procedure StartsWith(String1\$, String2\$)  Protected Result  If FindString(String1\$, String2\$, 1) =1 ; E.g Found in possition 1    Result =CountString(String1\$, String2\$)  EndIf  ProcedureReturn ResultEndProcedure Procedure EndsWith(String1\$, String2\$)  Protected Result, dl=Len(String1\$)-Len(String2\$)  If dl>=0 And Right(String1\$, Len(String2\$))=String2\$    Result =CountString(String1\$, String2\$)  EndIf  ProcedureReturn ResultEndProcedure`

And a verification

`If OpenConsole()  PrintN(Str(StartsWith("Rosettacode", "Rosetta")))           ; = 1  PrintN(Str(StartsWith("Rosettacode", "code")))              ; = 0  PrintN(Str(StartsWith("eleutherodactylus cruralis", "e")))  ; = 3  PrintN(Str(EndsWith  ("Rosettacode", "Rosetta")))  ; = 0  PrintN(Str(EndsWith  ("Rosettacode", "code")))     ; = 1  PrintN(Str(EndsWith  ("Rosettacode", "e")))        ; = 2   Print(#CRLF\$ + #CRLF\$ + "Press ENTER to exit"): Input()  CloseConsole()EndIf`

An alternate and more complete solution:

`Procedure startsWith(string1\$, string2\$)  ;returns one if string1\$ starts with string2\$, otherwise returns zero  If FindString(string1\$, string2\$, 1) = 1    ProcedureReturn 1  EndIf   ProcedureReturn 0EndProcedure Procedure contains(string1\$, string2\$, location = 0)  ;returns the location of the next occurrence of string2\$ in string1\$ starting from location,  ;or zero if no remaining occurrences of string2\$ are found in string1\$  ProcedureReturn FindString(string1\$, string2\$, location + 1)EndProcedure Procedure endsWith(string1\$, string2\$)  ;returns one if string1\$ ends with string2\$, otherwise returns zero  Protected ls = Len(string2\$)  If Len(string1\$) - ls >= 0 And Right(string1\$, ls) = string2\$    ProcedureReturn 1  EndIf  ProcedureReturn 0EndProcedure If OpenConsole()  PrintN(Str(startsWith("RosettaCode", "Rosetta")))           ; = 1, true  PrintN(Str(startsWith("RosettaCode", "Code")))              ; = 0, false   PrintN("")  PrintN(Str(contains("RosettaCode", "luck")))                ; = 0, no occurrences  Define location  Repeat    location = contains("eleutherodactylus cruralis", "e", location)    PrintN(Str(location))                                     ;display each occurrence: 1, 3, 7,  & 0 (no more occurrences)  Until location = 0   PrintN("")  PrintN(Str(endsWith  ("RosettaCode", "Rosetta")))            ; = 0, false  PrintN(Str(endsWith  ("RosettaCode", "Code")))               ; = 1, true   Print(#CRLF\$ + #CRLF\$ + "Press ENTER to exit"): Input()  CloseConsole()EndIf`
Output:
```1
0

0
1
3
7
0

0
1```

PowerShell

` "spicywiener".StartsWith("spicy")"spicywiener".Contains("icy")"spicywiener".EndsWith("wiener")"spicywiener".IndexOf("icy")[regex]::Matches("spicywiener", "i").count `
Output:
```True
True
True
2
2
```

Python

`"abcd".startswith("ab") #returns True"abcd".endswith("zn") #returns False"bb" in "abab" #returns False"ab" in "abab" #returns Trueloc = "abab".find("bb") #returns -1loc = "abab".find("ab") #returns 0loc = "abab".find("ab",loc+1) #returns 2`

Racket

` #lang racket(require srfi/13)(string-prefix? "ab" "abcd")(string-suffix? "cd" "abcd")(string-contains "abab" "bb")(string-contains "abab" "ba") `
Output:
```#t
#t
#f
1
```

Retro

`: startsWith? ( \$1 \$2 - f )  withLength &swap dip 0 swap ^strings'getSubset compare ; "abcdefghijkl" "abcde" startsWith?"abcdefghijkl" "bcd" startsWith? "abcdefghijkl" "bcd" ^strings'search"abcdefghijkl" "zmq" ^strings'search : endsWith? ( \$1 \$2 - f )  swap withLength + over getLength - compare ; "abcdefghijkl" "ijkl" endsWith?"abcdefghijkl" "abc" endsWith?`

REXX

Extra coding was added to take care of using plurals in the last output message.

`/*REXX program  demonstrates  some  basic   character string   testing  (for matching). */parse arg A B;                    LB=length(B)   /*obtain A and B from the command line.*/say 'string  A  = '   A                          /*display string   A   to the terminal.*/say 'string  B  = '   B                          /*   "       "     B    "  "      "    */say copies('░', 70)if left(A, LB)==B  then say  'string  A  starts with string  B'                   else say  "string  A  doesn't start with string  B"say                                              /* [↓] another method using COMPARE BIF*/          /*╔══════════════════════════════════════════════════════════════════════════╗            ║ if compare(A,B)==LB  then say  'string  A  starts with string  B'        ║            ║                      else say  "string  A  doesn't start with string  B" ║            ╚══════════════════════════════════════════════════════════════════════════╝*/p=pos(B, A)if p==0  then say  "string  A  doesn't contain string  B"         else say  'string  A  contains string  B  (starting in position'   p")"sayif right(A, LB)==b  then say 'string  A  ends with string  B'                    else say "string  A  doesn't end with string  B"say\$=;   p=0;                    do  until  p==0;        p=pos(B, A, p+1)                              if p\==0  then \$=\$','   p                              end   /*until*/\$=space(strip(\$, 'L', ","))                      /*elide extra blanks and leading comma.*/#=words(\$)                                       /*obtain number of words in  \$  string.*/if #==0  then say "string  A  doesn't contain string  B"         else say 'string  A  contains string  B '    #    " time"left('s', #>1),                  "(at position"left('s',  #>1)   \$")"  /*stick a fork in it, we're done*/`
output   when the following is specified (the five Marx brothers):   Chico_Harpo_Groucho_Zeppo_Gummo p
```string  A  =  Chico_Harpo_Groucho_Zeppo_Gummo
string  B  =  p
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

string  A  contains string  B  (starting in position 10)

string  A  doesn't end with string B

string  A  contains string  B  3  times (at positions 10, 23, 24)
```
output   when the following is specified:   Chico_Harpo_Groucho_Zeppo_Gummo Z
```string  A  =  Chico_Harpo_Groucho_Zeppo_Gummo
string  B  =  Z
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

string  A  contains string  B  (starting in position 21)

string  A  doesn't end with string  B

string  A  contains string  B  1  time (at position 21)
```
output   when the following is specified:   Chico_Harpo_Groucho_Zeppo_Gummo Chi
```string  A  =  Chico_Harpo_Groucho_Zeppo_Gummo
string  B  =  Chi
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
string  A  starts with string  B

string  A  contains string B  (starting in position 1)

string  A  doesn't end with string  B

string  A  contains string  B  1  time (at position 1)
```
output   when the following is specified:   Chico_Harpo_Groucho_Zeppo_Gummo mmo
```string  A  =  Chico_Harpo_Groucho_Zeppo_Gummo
string  B  =  mmo
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

string  A  contains string  B  (starting in position 29)

string  A  ends with string  B

string  A  contains string  B  1  time (at position 29)
```

Ring

` aString = "Welcome to the Ring Programming Language"bString = "Ring"bStringIndex = substr(aString,bString)if bStringIndex > 0 see "" + bStringIndex + " : " + bString ok `

Ruby

`p 'abcd'.start_with?('ab')  #returns truep 'abcd'.end_with?('ab')    #returns falsep 'abab'.include?('bb')     #returns falsep 'abab'.include?('ab')     #returns truep 'abab'['bb']              #returns nilp 'abab'['ab']              #returns "ab"p 'abab'.index('bb')        #returns nilp 'abab'.index('ab')        #returns 0p 'abab'.index('ab', 1)     #returns 2p 'abab'.rindex('ab')       #returns 2`

Run BASIC

`s1\$ = "abc def ghi klmnop"s2\$  = "abc"  ' begins withs3\$  = "ef"   ' is in the string s4\$  = "nop"  ' ends with sn2\$ = "abcx"  ' not begins withsn3\$ = "efx"   ' not in the string sn4\$ = "nopx"  ' not ends with if left\$(s1\$,len(s2\$)) <> s2\$ then a\$ = "Not "print "String:";s1\$;" does ";a\$;"begin with:";s2\$ if instr(s1\$,s3\$) = 0 then a\$ = "Not "print "String:";s1\$;" does ";a\$;"contain:";s3\$ if mid\$(s1\$,len(s1\$) + 1 - len(s4\$),len(s4\$)) <> s4\$ then a\$ = "Not "print "String:";s1\$;" does ";a\$;"end with:";s4\$ ' ----------- not -----------------------------printif left\$(s1\$,len(sn2\$)) <> sn2\$ then a\$ = "Not "print "String:";s1\$;" does ";a\$;"begin with:";sn2\$ if instr(s1\$,sn3\$) = 0 then a\$ = "Not "print "String:";s1\$;" does ";a\$;"contain:";sn3\$ if mid\$(s1\$,len(s1\$) + 1 - len(sn4\$),len(sn4\$)) <> sn4\$ then a\$ = "Not "print "String:";s1\$;" does ";a\$;"end with:";sn4\$`
Output:
```String:abc def ghi klmnop does begin with:abc
String:abc def ghi klmnop does contain:ef
String:abc def ghi klmnop does end with:nop

String:abc def ghi klmnop does Not begin with:abcx
String:abc def ghi klmnop does Not contain:efx
String:abc def ghi klmnop does Not end with:nopx```

Rust

`fn print_match(possible_match: Option<usize>) {    match possible_match {        Some(match_pos) => println!("Found match at pos {}", match_pos),        None => println!("Did not find any matches")    }} fn main() {    let s1 = "abcd";    let s2 = "abab";    let s3 = "ab";     // Determining if the first string starts with second string    assert!(s1.starts_with(s3));    // Determining if the first string contains the second string at any location    assert!(s1.contains(s3));    // Print the location of the match     print_match(s1.find(s3)); // Found match at pos 0    print_match(s1.find(s2)); // Did not find any matches    // Determining if the first string ends with the second string    assert!(s2.ends_with(s3));}`
` fn main(){    let hello = String::from("Hello world");    println!(" Start with \"he\" {} \n Ends with \"rd\" {}\n Contains \"wi\" {}",                                                         hello.starts_with("He"),                                                        hello.ends_with("ld"),                                                        hello.contains("wi"));}`
Output:
```Start with "he" true
Ends with "ld" true
Contains "wi" false
```

Scala

`"abcd".startsWith("ab") //returns true"abcd".endsWith("zn") //returns false"abab".contains("bb") //returns false"abab".contains("ab") //returns true var loc="abab".indexOf("bb") //returns -1loc = "abab".indexOf("ab") //returns 0loc = "abab".indexOf("ab", loc+1) //returns 2`

Seed7

`\$ include "seed7_05.s7i"; const proc: main is func  local    var integer: position is 0;  begin    writeln(startsWith("abcd", "ab")); # write TRUE    writeln(endsWith("abcd", "zn"));   # write FALSE    writeln(pos("abab", "bb") <> 0);   # write FALSE    writeln(pos("abab", "ab") <> 0);   # write TRUE    writeln(pos("abab", "bb"));        # write 0    position := pos("abab", "ab");    writeln(position);                 # position is 1    position := pos("abab", "ab", succ(position));    writeln(position);                 # position is 3  end func;`
Output:
```TRUE
FALSE
FALSE
TRUE
0
1
3
```

Sidef

`var first = "abc-abcdef-abcd";var second = "abc"; say first.begins_with(second);      #=> truesay first.contains(second);         #=> truesay first.ends_with(second);        #=> false # Get and print the location of the matchsay first.index(second);            #=> 0 # Find multiple occurrences of a stringvar pos = -1;while (pos = first.index(second, pos+1) != -1) {    say "Match at pos: #{pos}";}`

Smalltalk

`a startsWith: ba includesSubCollection: ba endsWith: ba indexOfSubCollection: ba indexOfSubCollection: b startingAt: pos`

SNOBOL4

`      s1 = 'abcdabefgab'      s2 = 'ab'      s3 = 'xy'      OUTPUT = ?(s1 ? POS(0) s2)  "1. " s2 " begins " s1      OUTPUT = ?(s1 ? POS(0) s3)  "1. " s3 " begins " s1  ;# fails       n = 0again s1 POS(n) ARB s2 @a                        :F(p3)      OUTPUT = "2. " s2 " found at position "+        a - SIZE(s2) " in " s1      n = a                                      :(again) p3    OUTPUT = ?(s1 ? s2 RPOS(0)) "3. " s2 " ends " s1END`
Output:
```1. ab begins abcdabefgab
2. ab found at position 0 in abcdabefgab
2. ab found at position 4 in abcdabefgab
2. ab found at position 9 in abcdabefgab
3. ab ends abcdabefgab```

Standard ML

`String.isPrefix "ab" "abcd"; (* returns true *)String.isSuffix "zn" "abcd"; (* returns false *)String.isSubstring "bb" "abab"; (* returns false *)String.isSubstring "ab" "abab"; (* returns true *)#2 (Substring.base (#2 (Substring.position "bb" (Substring.full "abab")))); (* returns 4 *)val loc = #2 (Substring.base (#2 (Substring.position "ab" (Substring.full "abab")))); (* returns 0 *)val loc' = #2 (Substring.base (#2 (Substring.position "ab" (Substring.extract ("abab", loc+1, NONE))))); (* returns 2 *)`

Swift

`var str = "Hello, playground"str.hasPrefix("Hell")           //Truestr.hasPrefix("hell")           //False str.containsString("llo")       //Truestr.containsString("xxoo")      //False str.hasSuffix("playground")     //Truestr.hasSuffix("world")          //False`

Tcl

In this code, we are looking in various ways for the string in the variable needle in the string in the variable haystack.

`set isPrefix    [string equal -length [string length \$needle] \$haystack \$needle]set isContained [expr {[string first \$needle \$haystack] >= 0}]set isSuffix    [string equal \$needle [string range \$haystack end-[expr {[string length \$needle]-1}] end]]`

Of course, in the cases where the needle is a glob-safe string (i.e., doesn't have any of the characters “*?[\” in), this can be written far more conveniently:

`set isPrefix    [string match  \$needle* \$haystack]set isContained [string match *\$needle* \$haystack]set isSuffix    [string match *\$needle  \$haystack]`

Another powerful technique is to use the regular expression engine in literal string mode:

`set isContained [regexp ***=\$needle \$haystack]`

This can be extended by getting the `regexp` to return the locations of the matches, enabling the other forms of match to be done:

`set matchLocations [regexp -indices -all -inline ***=\$needle \$haystack]# Each match location is a pair, being the index into the string where the needle started# to match and the index where the needle finished matching set isContained [expr {[llength \$matchLocations] > 0}]set isPrefix [expr {[lindex \$matchLocations 0 0] == 0}]set isSuffix [expr {[lindex \$matchLocations end 1] == [string length \$haystack]-1}]set firstMatchStart [lindex \$matchLocations 0 0]puts "Found \"\$needle\" in \"\$haystack\" at \$firstMatchStart"foreach location \$matchLocations {    puts "needle matched at index [lindex \$location 0]"}`

TUSCRIPT

` \$\$ MODE TUSCRIPTASK "string1", string1=""ASK "string2", string2="" IF (string1.sw.string2)   THENPRINT string1," starts with     ",string2ELSEPRINT string1," not starts with ",string2ENDIFSET beg=STRING (string1,string2,0,0,0,end)IF (beg!=0) THENPRINT string1," contains        ",string2PRINT "  starting in position ",begPRINT "  ending   in position ",endELSEPRINT string1," not contains    ",string2ENDIF IF (string1.ew.string2) THENPRINT string1," ends with       ",string2ELSEPRINT string1," not ends with   ",string2ENDIF `
Output:
```string1 >Rosetta Code
string2 >Code
Rosetta Code not starts with Code
Rosetta Code contains        Code
starting in position 9
ending   in position 13
Rosetta Code ends with       Code
```

TXR

TXR Lisp

`(tree-case *args*  ((big small)   (cond     ((< (length big) (length small))      (put-line `@big is shorter than @small`))     ((str= big small)      (put-line `@big and @small are equal`))     ((starts-with small big)      (put-line `@small is a prefix of @big`))     ((ends-with small big)      (put-line `@small is a suffix of @big`))     (t (iflet ((pos (search-str big small)))          (put-line `@small occurs in @big at position @pos`)          (put-line `@small does not occur in @big`)))))  (otherwise    (put-line `usage: @(ldiff *full-args* *args*) <bigstring> <smallstring>`)))`
Output:
```\$ txr cmatch2.tl x
usage: txr cmatch2.tl <bigstring> <smallstring>
\$ txr cmatch2.tl x y z
usage: txr cmatch2.tl <bigstring> <smallstring>
\$ txr cmatch2.tl catalog cat
cat is a prefix of catalog
\$ txr cmatch2.tl catalog log
log is a suffix of catalog
\$ txr cmatch2.tl catalog at
at occurs in catalog at position 1
\$ txr cmatch2.tl catalog catalogue
catalog is shorter than catalogue
\$ txr cmatch2.tl catalog catalog
catalog and catalog are equal
\$ txr cmatch2.tl catalog dog
dog does not occur in catalog```

Pattern Language

`@line@(cases)@  line@  (output)second line is the same as first line@  (end)@(or)@  (skip)@line@  (output)first line is a suffix of the second line@  (end)@(or)@  [email protected](skip)@  (output)first line is a suffix of the second line@  (end)@(or)@  [email protected]@(skip)@  (output)first line is embedded in the second line at position @(length prefix)@  (end)@(or)@  (output)first line is not found in the second line@  (end)@(end)`
Output:
```\$ txr cmatch.txr -
123
01234
first line is embedded in the second line at position 1
\$ txr cmatch.txr -
123
0123
first line is a suffix of the second line```

VBScript

`Function StartsWith(s1,s2)	StartsWith = False	If Left(s1,Len(s2)) = s2 Then		StartsWith = True	End IfEnd Function Function Contains(s1,s2)	Contains = False	If InStr(1,s1,s2) Then		Contains = True & " at positions "		j = 1		Do Until InStr(j,s1,s2) = False			Contains = Contains & InStr(j,s1,s2) & ", "			If j = 1 Then				If Len(s2) = 1 Then					j = j + InStr(j,s1,s2)				Else					j = j + (InStr(j,s1,s2) + (Len(s2) - 1))				End If			Else				If Len(s2) = 1 Then					j = j + ((InStr(j,s1,s2) - j) + 1)				Else					j = j + ((InStr(j,s1,s2) - j) + (Len(s2) - 1))				End If			End If		Loop	End IfEnd Function Function EndsWith(s1,s2)	EndsWith = False	If Right(s1,Len(s2)) = s2 Then		EndsWith = True	End IfEnd Function WScript.StdOut.Write "Starts with test, 'foo' in 'foobar': " & StartsWith("foobar","foo")WScript.StdOut.WriteLineWScript.StdOut.Write "Contains test, 'o' in 'fooooobar': " & Contains("fooooobar","o")WScript.StdOut.WriteLineWScript.StdOut.Write "Ends with test, 'bar' in 'foobar': " & EndsWith("foobar","bar")`
Output:
```Starts with test, 'foo' in 'foobar': True
Contains test, 'o' in 'fooooobar': True at positions 2, 3, 4, 5, 6,
Ends with test, 'bar' in 'foobar': True
```

XPL0

`include c:\cxpl\codes;  \intrinsic 'code' declarationsstring 0;               \use zero-terminated strings func StrLen(A);         \Return number of characters in a stringchar A;int  I;for I:= 0 to -1>>1-1 do    if A(I) = 0 then return I; func StrFind(A, B);     \Search for string B in string A\Returns index of first occurrence of string B in A, or -1 if B is not foundchar A, B;              \strings to be comparedint  LA, LB, I, J;[LA:= StrLen(A); LB:= StrLen(B); for I:= 0 to LA-LB do    [for J:= 0 to LB-1 do        if B(J) # A(J+I) then J:= LB+1;    if J = LB then return I;    \found    ];return -1;]; char Str;  int I, J;[Str:= "pack my box with";\       0123456789012345Text(0, if StrFind(Str, "pack") = 0 then "yes" else "no");  CrLf(0);    \1.Text(0, if StrFind(Str,  "ack") = 0 then "yes" else "no");  CrLf(0);I:= StrFind(Str, "x w");Text(0, if I >= 0 then "yes" else "no");                                \2.Text(0, ", at offset ");  IntOut(0, I);  CrLf(0);I:= 0;  J:= 0;          \offsets of space charactersloop    [I:= StrFind(Str+J, " ");        if I < 0 then quit;        IntOut(0, I+J); ChOut(0, ^ );        J:= J+I+1;        ];CrLf(0);Text(0, if StrFind(Str, "X w") >= 0 then "yes" else "no");  CrLf(0);Text(0, if StrFind(Str, "with") = StrLen(Str)-StrLen("with") then "yes" else "no");  CrLf(0); \3.Text(0, if StrFind(Str, "x w" ) = StrLen(Str)-StrLen("x w" ) then "yes" else "no");  CrLf(0);]`
Output:
```yes
no
yes, at offset 10
4 7 11
no
yes
no
```

zkl

`fcn f(text,p){ if(text.find(p)==0)println("Yep") else println("Nope") }f("foobar","foo") //--> Yepf("foobar","bar") //--> Nope`
`fcn f(text,p){ if(Void!=(n:=text.find(p)))println("Contained @",n) else println("Nope") }f("foobar","ob")   //--> Contained @2f("foobar","food") //--> Nope`
`fcn f(text,p){    if( Void!=(n:=text.rfind(p)) and n+p.len()==text.len() )      println("tail gunner") else println("Nope")}f("foobar","r"); f("foobar","ar"); //--> tail gunnersf("foobar","ob");  //--> Nopef("foobarfoobar","bar"); //--> tail gunner`