for ($book1, $book2, $book3, $book4, $book5, $book6) -> $b
{ say $b
.subst(/ \S <( (\-+) \h )> \S /, {" $0 "}, :global)
.subst(/ \S <( \h (\-+) )> \S /, {" $0 "}, :global)
.subst(/ \S <( (\-) \v )> \S /, {"$0"}, :global) #fixes hyphenated words w/embedded newlines
}
Sample Input:
my $book1 = "Don Quixote- Miguel de Cervantes";
my $book2 = "Les Misérables -Victor Hugo";
my $book3 = "War and Peace - Leo Tolstoy";
my $book4 = "Moby-Dick; or, The Whale- Herman Melville";
my $book5 = "Winnie-the-Pooh --A. A. Milne";
my $book6 = "Slaughterhouse-\nFive- Kurt Vonnegut";
Sample Output:
Don Quixote - Miguel de Cervantes
Les Misérables - Victor Hugo
War and Peace - Leo Tolstoy
Moby-Dick; or, The Whale - Herman Melville
Winnie-the-Pooh -- A. A. Milne
Slaughterhouse-Five - Kurt Vonnegut
For this problem I would probably start by asking how these erroneous entries found their way into the data at hand. Was it the product of concatenation? Or informal (manual) entry? The first is fixable, the second might be a primary application of the Raku programming language (i.e. making informal, manual text entries more formal). This answer follows the excellent examples already posted, but (in contrast) uses a $0 capture to re-position the "-" field separator. In brief:
The first .subst(...) command globally captures one-or-more hyphens when followed by a single horizontal whitespace, and places the equivalent number of hyphens between the Title and Author (hyphens surrounded by whitespace).
The second .subst(...) command globally captures one-or-more hyphens when preceded by a horizontal whitespace, and places the equivalent number of hyphens between the Title and Author (hyphens surrounded by whitespace).
The third .subst(...) command globally captures a single hyphen when followed by a single vertical whitespace (e.g. newline), and removes the vertical whitespace. Hyphens followed by horizontal whitespace remain untouched. Note, for this the third .subst(...) command, the replacement can simply be written as "-" (i.e. no need to use $0).
Note: the first two .subst statements can be combined with | OR:
.subst(/ \S <( (\-+) \h | \h (\-+) )> \S /, {" "~$0~" "}, :global)
Why go to all this trouble? Well, the first reason is that a more 'pedestrian' approach is more robust to complicated input (e.g. hyphenated words). In fact, some answers already posted may not handle hyphenated book titles and/or author names, which are handled gracefully (above and below, note alternate replacement form):
~$ cat book_author.txt
Don Quixote- Miguel de Cervantes
Les Misérables -Victor Hugo
War and Peace - Leo Tolstoy
Moby-Dick; or, The Whale- Herman Melville
Winnie-the-Pooh --A. A. Milne
Slaughterhouse-
Five- Kurt Vonnegut
~$ cat book_author.txt | raku -e 'say lines.join("\n")
.subst(/ \S <( (\-+) \h )> \S /, {" "~$0~" "}, :global)
.subst(/ \S <( \h (\-+) )> \S /, {" "~$0~" "}, :global)
.subst(/ \S <( \- \v )> \S /, "-", :global);'
Don Quixote - Miguel de Cervantes
Les Misérables - Victor Hugo
War and Peace - Leo Tolstoy
Moby-Dick; or, The Whale - Herman Melville
Winnie-the-Pooh -- A. A. Milne
Slaughterhouse-Five - Kurt Vonnegut
The second reason is such an answer can be used to modify text with other separators, such as Title | Author data, wherein title is separated from author by a vertical bar. The third reason is capturing (e.g. using $0) is adapted to a wide variety of problems, such as making multiple identical separator characters like -- or || into single-character separators (note yet another way of writing the replacement, this time adding .comb[0]):
~$ cat book_bar_author.txt
Don Quixote| Miguel de Cervantes
Les Misérables |Victor Hugo
War and Peace | Leo Tolstoy
Moby-Dick; or, The Whale| Herman Melville
Winnie-the-Pooh ||A. A. Milne
Slaughterhouse-
Five| Kurt Vonnegut
~$ cat book_bar_author.txt | raku -e 'say lines.join("\n")
.subst(/ \S <( (\|+) \h )> \S /, {"",$0.comb[0],""}, :global)
.subst(/ \S <( \h (\|+) )> \S /, {"",$0.comb[0],""}, :global)
.subst(/ \S <( \- \v )> \S /, "-", :global);'
Don Quixote | Miguel de Cervantes
Les Misérables | Victor Hugo
War and Peace | Leo Tolstoy
Moby-Dick; or, The Whale | Herman Melville
Winnie-the-Pooh | A. A. Milne
Slaughterhouse-Five | Kurt Vonnegut