1

I'd need to set out the following code in order to identify dates with a regex within a text and thus modify the pattern (truncating the last hh:mm:ss part and adding the type in literal way e.g., "^^date") I have just started to approach Perl, I am not familiar with that. The code sounds like this following:

use warnings;
use strict;

my $filename = 'C:\Users\M\Desktop\products.txt';
# in which strings like this are set: 'aaaa-mm-ddThh:mm:ss' ex. 1991-06-19T00:00:01

    open my $IN, '<', $filename or die $!;

    while (<$IN>) {
        if ($_ =~ m/\nnnn\-\nn\-\nn\T\nn\:\nn\:\nn/)
        {    s/^(\ )=.*/"1.0"^^xsd:date/;}
    }

Most of the syntax is not correct. Where did it go wrong?

Mario Ross
  • 11
  • 2
  • If you want to put code in your question, then please select the text and press the `{}` button to format it correctly. I've fixed it for you now, but please consider doing it yourself next time. – Dave Cross Mar 25 '21 at 11:19
  • Please see following [example](https://rextester.com/QUMK95229) for compliance with your question. – Polar Bear Mar 28 '21 at 23:00

1 Answers1

1

I've put your code in a file called broken. I can then check the syntax by running:

$ perl -c broken

This gives the following errors:

Unrecognized escape \T passed through in regex; marked by <-- HERE in m/\nnnn\-\nn\-\nn\T <-- HERE \nn\:\nn\:\nn)
        {    s/ at broken line 11.
Unmatched ) in regex; marked by <-- HERE in m/\nnnn\-\nn\-\nn\T\nn\:\nn\:\nn) <-- HERE
        {    s/ at broken line 11.

The first is really only a warning. It's telling you that \T isn't recognised as a special escape sequence in Perl regular expressions. As we want to match a "T", we can just remove the \.

The second error is more serious, but it's easier to fix. It says that you have an unmatched ) at the end of your regex. Of course, that ) is supposed to be the end of the if (...) statement. So why is Perl seeing it as part of the regex? Well, it's because the end of the regex needs to be marked with a closing / character - which you have missed. Let's add it back, so the regex line in your code looks like this:

if ($_ =~ m/\nnnn\-\nn\-\nnT\nn\:\nn\:\nn/)

We can then try the syntax check again. We get another message:

Missing right curly or square bracket at broken line 12, at end of line
syntax error at broken line 12, at EOF

As there are no square brackets in the code, the problem will be with curly brackets. Of course, all curly brackets need to be balanced (for each opening bracket we need a matching closing bracket) and it doesn't take much investigation to see that you've missed a closing curly bracket somewhere. You have two opening curly brackets (one for the while and one for the if) and only one closing curly bracket. So let's add another one and try again.

Your code now looks like this:

use warnings;
use strict;

my $filename = 'C:\Users\M\Desktop\products.txt';
# in which strings like this are set: 'aaaa-mm-ddThh:mm:ss' ex. 1991-06-19T00:00:01

    open my $IN, '<', $filename or die $!;

    while (<$IN>) {
        if ($_ =~ m/\nnnn\-\nn\-\nnT\nn\:\nn\:\nn/)
        {    s/^(\ )=.*/"1.0"^^xsd:date/; }
    }

And running the syntax check tells us:

broken syntax OK

('broken' is, of course, the filename. It's not saying we have broken syntax!)

So the syntax is now all fixed. Any remaining problems are with the semantics - what your code is actually trying to do. You haven't explained what you're trying to achieve particularly well (it would be nice to have more sample inputs and their associated outputs) but I can, at least, point out that your regex won't match what you think it matches. You seem to think that n is a special character in Perl regexes that matches a digit. That's not the case. And n in a regex matches the character "n". To match a digit, we use \d. You can get more information from the regex tutorial or the regex manual page.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • I never used a `my` to define a handle. Just `open IN, '<', $filename' or die $!;` even in strict mode. And then `` and so on. Is it a new standard using handles like a scalar? – Andy A. Mar 25 '21 at 12:53
  • 1
    @AndyU. using lexical filehandles is not new. I don't know precisely when it was introduced, but it seems that it works [since at least Perl 5.6](https://www.perlmonks.org/?node_id=394068) (released in 2000). I don't know either when people started really using them, but I found this [2009 SO answer](https://stackoverflow.com/a/1479771/4990392) that recommends using lexical file handles. So, using lexical file handles is definitely better, and definitely not new ;-) – Dada Mar 25 '21 at 13:51
  • Thank you Dave, I've corrected the syntax. My goal is to replace strings with date "aaaa-mm-ddThh:mm:ss" with data formats that can be readable in Turtle. I attach a few examples of the current date format: "1971-06-19T00:00:01" ; "1990-04-07T00:00:01" . and of how they should looks like: "1971-06-19"^^xsd:date "1990-04-07"^^xsd:date Best, – Mario Ross Mar 28 '21 at 17:58
  • @MarioRoss: Please don't put important details like that in a comment, where they're likely to be missed. Instead, edit your question to add a list of inputs and what the associated outputs should be. – Dave Cross Mar 29 '21 at 06:44
  • @MarioRoss: In fact, given that the main thrust of this question was about the syntax errors (which are now fixed), it's probably better to accept an answer on this question and post a new one explaining exactly what your next problem is. – Dave Cross Mar 29 '21 at 06:45