| ... | ... | @@ -1876,7 +1876,11 @@ test "rotate" { |
| 1876 | 1876 | |
| 1877 | 1877 | /// Replace needle with replacement as many times as possible, writing to an output buffer which is assumed to be of |
| 1878 | 1878 | /// appropriate size. Use replacementSize to calculate an appropriate buffer size. |
| 1879 | /// The needle must not be empty. |
| 1879 | 1880 | pub fn replace(comptime T: type, input: []const T, needle: []const T, replacement: []const T, output: []T) usize { |
| 1881 | // Empty needle will loop until output buffer overflows. |
| 1882 | assert(needle.len > 0); |
| 1883 | |
| 1880 | 1884 | var i: usize = 0; |
| 1881 | 1885 | var slide: usize = 0; |
| 1882 | 1886 | var replacements: usize = 0; |
| ... | ... | @@ -1899,22 +1903,48 @@ pub fn replace(comptime T: type, input: []const T, needle: []const T, replacemen |
| 1899 | 1903 | test "replace" { |
| 1900 | 1904 | var output: [29]u8 = undefined; |
| 1901 | 1905 | var replacements = replace(u8, "All your base are belong to us", "base", "Zig", output[0..]); |
| 1906 | var expected: []const u8 = "All your Zig are belong to us"; |
| 1902 | 1907 | testing.expect(replacements == 1); |
| 1903 | | testing.expect(eql(u8, output[0..], "All your Zig are belong to us")); |
| 1908 | testing.expectEqualStrings(expected, output[0..expected.len]); |
| 1904 | 1909 | |
| 1905 | 1910 | replacements = replace(u8, "Favor reading code over writing code.", "code", "", output[0..]); |
| 1911 | expected = "Favor reading over writing ."; |
| 1906 | 1912 | testing.expect(replacements == 2); |
| 1907 | | testing.expect(eql(u8, output[0..], "Favor reading over writing .")); |
| 1913 | testing.expectEqualStrings(expected, output[0..expected.len]); |
| 1914 | |
| 1915 | // Empty needle is not allowed but input may be empty. |
| 1916 | replacements = replace(u8, "", "x", "y", output[0..0]); |
| 1917 | expected = ""; |
| 1918 | testing.expect(replacements == 0); |
| 1919 | testing.expectEqualStrings(expected, output[0..expected.len]); |
| 1920 | |
| 1921 | // Adjacent replacements. |
| 1922 | |
| 1923 | replacements = replace(u8, "\\n\\n", "\\n", "\n", output[0..]); |
| 1924 | expected = "\n\n"; |
| 1925 | testing.expect(replacements == 2); |
| 1926 | testing.expectEqualStrings(expected, output[0..expected.len]); |
| 1927 | |
| 1928 | replacements = replace(u8, "abbba", "b", "cd", output[0..]); |
| 1929 | expected = "acdcdcda"; |
| 1930 | testing.expect(replacements == 3); |
| 1931 | testing.expectEqualStrings(expected, output[0..expected.len]); |
| 1908 | 1932 | } |
| 1909 | 1933 | |
| 1910 | 1934 | /// Calculate the size needed in an output buffer to perform a replacement. |
| 1935 | /// The needle must not be empty. |
| 1911 | 1936 | pub fn replacementSize(comptime T: type, input: []const T, needle: []const T, replacement: []const T) usize { |
| 1937 | // Empty needle will loop forever. |
| 1938 | assert(needle.len > 0); |
| 1939 | |
| 1912 | 1940 | var i: usize = 0; |
| 1913 | 1941 | var size: usize = input.len; |
| 1914 | | while (i < input.len) : (i += 1) { |
| 1942 | while (i < input.len) { |
| 1915 | 1943 | if (mem.indexOf(T, input[i..], needle) == @as(usize, 0)) { |
| 1916 | 1944 | size = size - needle.len + replacement.len; |
| 1917 | 1945 | i += needle.len; |
| 1946 | } else { |
| 1947 | i += 1; |
| 1918 | 1948 | } |
| 1919 | 1949 | } |
| 1920 | 1950 | |
| ... | ... | @@ -1923,9 +1953,15 @@ pub fn replacementSize(comptime T: type, input: []const T, needle: []const T, re |
| 1923 | 1953 | |
| 1924 | 1954 | test "replacementSize" { |
| 1925 | 1955 | testing.expect(replacementSize(u8, "All your base are belong to us", "base", "Zig") == 29); |
| 1926 | | testing.expect(replacementSize(u8, "", "", "") == 0); |
| 1927 | 1956 | testing.expect(replacementSize(u8, "Favor reading code over writing code.", "code", "") == 29); |
| 1928 | 1957 | testing.expect(replacementSize(u8, "Only one obvious way to do things.", "things.", "things in Zig.") == 41); |
| 1958 | |
| 1959 | // Empty needle is not allowed but input may be empty. |
| 1960 | testing.expect(replacementSize(u8, "", "x", "y") == 0); |
| 1961 | |
| 1962 | // Adjacent replacements. |
| 1963 | testing.expect(replacementSize(u8, "\\n\\n", "\\n", "\n") == 2); |
| 1964 | testing.expect(replacementSize(u8, "abbba", "b", "cd") == 8); |
| 1929 | 1965 | } |
| 1930 | 1966 | |
| 1931 | 1967 | /// Perform a replacement on an allocated buffer of pre-determined size. Caller must free returned memory. |