@@ -341,16 +341,19 @@ defmodule String do
341
341
iex> String.split("abc", ~r{b}, include_captures: true)
342
342
["a", "b", "c"]
343
343
344
- Splitting on empty patterns returns graphemes:
344
+ Splitting on empty string returns graphemes:
345
345
346
346
iex> String.split("abc", "")
347
- ["a", "b", "c", ""]
347
+ ["", " a", "b", "c", ""]
348
348
349
349
iex> String.split("abc", "", trim: true)
350
350
["a", "b", "c"]
351
351
352
- iex> String.split("abc", "", parts: 2)
353
- ["a", "bc"]
352
+ iex> String.split("abc", "", parts: 1)
353
+ ["abc"]
354
+
355
+ iex> String.split("abc", "", parts: 3)
356
+ ["", "a", "bc"]
354
357
355
358
A precompiled pattern can also be given:
356
359
@@ -379,7 +382,19 @@ defmodule String do
379
382
Regex . split ( pattern , string , options )
380
383
end
381
384
382
- def split ( string , pattern , [ ] ) when is_binary ( string ) and pattern != "" do
385
+ def split ( string , "" , options ) when is_binary ( string ) do
386
+ parts = Keyword . get ( options , :parts , :infinity )
387
+ index = parts_to_index ( parts )
388
+ trim = Keyword . get ( options , :trim , false )
389
+
390
+ if trim == false and index != 1 do
391
+ [ "" | split_empty ( string , trim , index - 1 ) ]
392
+ else
393
+ split_empty ( string , trim , index )
394
+ end
395
+ end
396
+
397
+ def split ( string , pattern , [ ] ) when is_tuple ( pattern ) or is_binary ( string ) do
383
398
:binary . split ( string , pattern , [ :global ] )
384
399
end
385
400
@@ -393,6 +408,16 @@ defmodule String do
393
408
defp parts_to_index ( :infinity ) , do: 0
394
409
defp parts_to_index ( n ) when is_integer ( n ) and n > 0 , do: n
395
410
411
+ defp split_empty ( "" , true , 1 ) , do: [ ]
412
+ defp split_empty ( string , _ , 1 ) , do: [ string ]
413
+
414
+ defp split_empty ( string , trim , count ) do
415
+ case next_grapheme ( string ) do
416
+ { h , t } -> [ h | split_empty ( t , trim , count - 1 ) ]
417
+ nil -> split_empty ( "" , trim , 1 )
418
+ end
419
+ end
420
+
396
421
defp split_each ( "" , _pattern , true , 1 ) , do: [ ]
397
422
defp split_each ( string , _pattern , _trim , 1 ) when is_binary ( string ) , do: [ string ]
398
423
@@ -424,26 +449,37 @@ defmodule String do
424
449
["1", "2", "3", "4"]
425
450
426
451
iex> String.splitter("abcd", "") |> Enum.take(10)
427
- ["a", "b", "c", "d", ""]
452
+ ["", " a", "b", "c", "d", ""]
428
453
429
454
iex> String.splitter("abcd", "", trim: true) |> Enum.take(10)
430
455
["a", "b", "c", "d"]
431
456
432
457
"""
433
458
@ spec splitter ( t , pattern , keyword ) :: Enumerable . t ( )
434
- def splitter ( string , pattern , options \\ [ ] ) do
459
+ def splitter ( string , pattern , options \\ [ ] )
460
+
461
+ def splitter ( string , "" , options ) do
462
+ if Keyword . get ( options , :trim , false ) do
463
+ Stream . unfold ( string , & next_grapheme / 1 )
464
+ else
465
+ Stream . unfold ( :match , & do_empty_splitter ( & 1 , string ) )
466
+ end
467
+ end
468
+
469
+ def splitter ( string , pattern , options ) do
435
470
pattern = maybe_compile_pattern ( pattern )
436
471
trim = Keyword . get ( options , :trim , false )
437
472
Stream . unfold ( string , & do_splitter ( & 1 , pattern , trim ) )
438
473
end
439
474
475
+ defp do_empty_splitter ( :match , string ) , do: { "" , string }
476
+ defp do_empty_splitter ( :nomatch , _string ) , do: nil
477
+ defp do_empty_splitter ( "" , _ ) , do: { "" , :nomatch }
478
+ defp do_empty_splitter ( string , _ ) , do: next_grapheme ( string )
479
+
440
480
defp do_splitter ( :nomatch , _pattern , _ ) , do: nil
441
- defp do_splitter ( "" , _pattern , true ) , do: nil
442
481
defp do_splitter ( "" , _pattern , false ) , do: { "" , :nomatch }
443
-
444
- defp do_splitter ( bin , "" , _trim ) do
445
- next_grapheme ( bin )
446
- end
482
+ defp do_splitter ( "" , _pattern , true ) , do: nil
447
483
448
484
defp do_splitter ( bin , pattern , trim ) do
449
485
case :binary . split ( bin , pattern ) do
@@ -453,7 +489,6 @@ defmodule String do
453
489
end
454
490
end
455
491
456
- defp maybe_compile_pattern ( "" ) , do: ""
457
492
defp maybe_compile_pattern ( pattern ) when is_tuple ( pattern ) , do: pattern
458
493
defp maybe_compile_pattern ( pattern ) , do: :binary . compile_pattern ( pattern )
459
494
0 commit comments