Perl - Capture Specific number of words from a string

Viewed 310

I have a lengthy string in a perl variable which has more than 500 words.

$mytext = "This text goes on and on and on........";

Basically, this lengthy string can contain anything and everything including all kinds of special characters. It can include special characters (like apostrophes - it's a division of cleo's business), numbers (like - incorporated on August 2, 2001), commas, semicolons and apostrophe's (like - through its different divisions, the business's earnings), special characters (like '&', single and double quotes)

My requirement is to extract a specific number of words (not characters) from the start of the string. For example, I may need to pick the first 200 words. I know that there is a builtin substr function:

substr($mytext, $start, $length)

but it extracts the number of characters.
How can I extract the number of words instead?

3 Answers

You can do this with the split function :

  • it accepts a regexp : here \W+ will split the string everytime a non-word character (or sequence of such characters) is encountered
  • it offers an option that limits how many times the string will be cut (which effectively controls the maximum number of parts that you have in the output).

Code :

my $mytext = "This text goes on and on and on........";
my $nb_words = 20;
my @words = split(/\W+/, $mytext, $nb_words + 1);
pop @words; # the last item contains the remaining of the string

If you need a part of the text containing the first N words, with all the spaces, punctuation, etc

my $text = q(one two, three-four five etc);
my $n = 4;

my ($subtext) = $text =~ /((?:\w+.*?){$n})/; 
say $subtext;

with the subtext string

one two, three-four

Adjust what you consider a "word" in the regex. For example, if hyphens are acceptable change \w+ to [\w-]+ (in which case three-four is one "word" so five makes it in as well)

If you need a list of words, you can also "tokenize" (and capture) with a regex

my $n = 4;
my @words;

push @words, $1 while $text =~ /(\w+)/g and @words < $n;
say "@words";

for

one two three four

where you'd again change \w if your "words" are other than letters, numbers and underscore.

If it's OK to define a word by all character that is not a space, you can do:

my $str = <<'EOD';
Basically, this lengthy string can contain anything and everything including all kinds of special characters. It can include special characters (like apostrophes - it's a division of cleo's business), numbers (like - incorporated on August 2, 2001), commas, semicolons and apostrophe's (like - through its different divisions, the business's earnings), special characters (like '&', single and double quotes)
EOD

my ($wd) = $str =~ /((?:\S+\s+){1,30})/; # I've limited the length at 30 for testing.
say $wd;

Output:

Basically, this lengthy string can contain anything and everything including all kinds of special characters. It can include special characters (like apostrophes - it's a division of cleo's business), numbers

Related