Leaning toothpick syndromeIn computer programming, leaning toothpick syndrome (LTS) is the situation in which a quoted expression becomes unreadable because it contains a large number of escape characters, usually backslashes ("\"), to avoid delimiter collision.[1][2] The official Perl documentation[3] introduced the term to wider usage; there, the phrase is used to describe regular expressions that match Unix-style paths, in which the elements are separated by slashes LTS appears in many programming languages and in many situations, including in patterns that match Uniform Resource Identifiers (URIs) and in programs that output quoted text. Many quines fall into the latter category. Pattern exampleConsider the following Perl regular expression intended to match URIs that identify files under the m/ftp:\/\/[^\/]*\/pub\//
Perl, like sed before it, solves this problem by allowing many other characters to be delimiters for a regular expression. For example, the following three examples are equivalent to the expression given above: m{ftp://[^/]*/pub/} m#ftp://[^/]*/pub/# m!ftp://[^/]*/pub/! Or this common translation to convert backslashes to forward slashes: tr/\\/\//
may be easier to understand when written like this: tr{\\}{/}
Quoted-text exampleA Perl program to print an HTML link tag, where the URL and link text are stored in variables print "<a href=\"$url\">$text</a>";
Using single quotes to delimit the string is not feasible, as Perl does not expand variables inside single-quoted strings. The code below, for example, would not work as intended: print '<a href="$url">$text</a>'
Using the printf('<a href="%s">%s</a>', $url, $text);
The print qq{<a href="$url">$text</a>};
print qq|<a href="$url">$text</a>|;
print qq(<a href="$url">$text</a>);
Here documents are especially well suited for multi-line strings; however, Perl here documents hadn't allowed for proper indentation before v5.26.[4] This example shows the Perl syntax: print <<HERE_IT_ENDS;
<a href="$url">$text</a>
HERE_IT_ENDS
Other languagesC#The C# programming language handles LTS by the use of the string filePath = @"C:\Foo\Bar.txt";
rather than otherwise requiring: string filePath = "C:\\Foo\\Bar.txt";
C++The C++11 standard adds raw strings: std::string filePath = R"(C:\Foo\Bar.txt)";
If the string contains the characters std::regex re{ R"d(s/"\([^"]*\)"/'\1'/g)d" };
GoGo indicates that a string is raw by using the backtick as a delimiter: s := `C:\Foo\Bar.txt`
Raw strings may contain any character except backticks; there is no escape code for a backtick in a raw string. Raw strings may also span multiple lines, as in this example, where the strings s := `A string that
spans multiple
lines.`
t := "A string that\nspans multiple\nlines."
PythonPython has a similar construct using filePath = r"C:\Foo\Bar.txt"
One can also use them together with triple quotes: example = r"""First line : "C:\Foo\Bar.txt"
Second line : nothing"""
RR has a similar construct using filePath <- r"(C:\Foo\Bar.txt)"
For raw strings that contain string <- r"{Text with (some) parentheses}"
For additional flexibility, a number of dashes can be placed between the opening quote and the opening delimiter, as long as the same number of dashes appear between the closing delimiter and the closing quote. RubyRuby uses single quote to indicate raw string: filePath = 'C:\Foo\Bar.txt'
It also has regex percent literals with choice of delimiter like Perl: %r{ftp://[^/]*/pub/}
%r#ftp://[^/]*/pub/#
%r!ftp://[^/]*/pub/!
RustRust uses a variant of the "\x52"; // R
r"\x52"; // \x52
r#""foo""#; // "foo"
r##"foo #"# bar"##; // foo #"# bar
The literal starts with ScalaScala allows usage of triple quotes in order to prevent escaping confusion: val filePath = """C:\Foo\Bar.txt"""
val pubPattern = """ftp://[^/]*/pub/"""r
The triple quotes also allow for multiline strings, as shown here: val text = """First line,
second line."""
SedSed regular expressions, particularly those using the "s" operator, are much similar to Perl (sed is a predecessor to Perl). The default delimiter is "/", but any delimiter can be used; the default is s/ftp:\/\/[^\/]*\/pub\//foo/
Using an exclamation point ("!") as delimiter instead yields s!ftp://[^/]*/pub/!foo!
See alsoReferences
|