簡體   English   中英

如何使用 Perl 在 Regex 中使用分詞、星號、分詞?

[英]How to use word break, asterisk, word break in Regex with Perl?

我在 Perl 中有一個復雜的預編譯正則表達式。 在大多數情況下,正則表達式很好,可以匹配它應該匹配的所有內容,而沒有不應該匹配的內容。 除了一分。

基本上我的正則表達式看起來像:

my $regexp = qr/\b(FOO|BAR|\*)\b/;

不幸的是m/\\b\\*\\b/不會匹配example, * 只有m/\\*/會做,因為誤報我不能使用。 有什么解決方法嗎?

來自評論 -誤報是: ** , example* , example* exam*ple

正則表達式的用途是什么? -它應該提取同事輸入產品數據的關鍵字(一個是單個星號)。 目標是將這些信息從自由文本字段中移到原子字段中。

聽起來您想將*視為單詞字符。

\b

相當於

(?x: (?<!\w)(?=\w) | (?<=\w)(?!\w) )

所以你要

(?x: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )

申請后,您將獲得以下信息:

qr/
    (?: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
    (FOO|BAR|\*)
    (?: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
/x

但鑒於我們對中間表達式的了解,可以將其簡化為以下內容:

qr/(?<![\w*])(FOO|BAR|\*)(?![\w*])/

問題是 Perl 不認為*是“單詞字符”,因此不識別空格和星號之間的單詞邊界(而它確實識別rfoobar**之間的邊界)。

解決的辦法是先決定要考慮的“字”,“無字”的字符,然后檢查該明確的東西。 例如,如果您希望您的單詞由字母 'A' 到 'Z'(或其小寫版本)和* ,並且其他所有內容都被視為非單詞字符,您可以使用:

/(?<![A-Za-z*])(FOO|BAR|\*)(?![A-Za-z*])/

這將匹配字符串FOOBAR* ,前提是它們前面或后面沒有匹配[A-Za-z*]的字符。

同樣,如果您想將除空格以外的所有內容都視為非單詞字符,您可以使用:

/(?<!\S)(FOO|BAR|\*)(?!\S)/

它將匹配FOOBAR* ,前提是它們前面或后面沒有非空白字符。

怎么樣:

my $regexp = qr/(?:\b(FOO|BAR)\b)|(?:^| )\*(?:$| )/;

在行動:

my $re = qr~(?:\b(FOO|BAR)\b)|(?:^| )\*(?:$| )~;
while(<DATA>) {
    chomp;
    say (/$re/ ? "OK : $_" : "KO : $_");
}


__DATA__
FOO
BAR
*
exam*ple
example*

輸出:

OK : FOO
OK : BAR
OK : *
KO : exam*ple
KO : example*

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM