编写一个适当的正则表达式,处理多个空格

huangapple go评论55阅读模式
英文:

Writing a proper regular expression that handles multiple spaces

问题

以下是您要提取的信息的翻译:

NOWAKOWSKA
NOWAK_S6_2
KOWALSKA_S6_
NOWACKI S6_

您之前使用的正则表达式是%^Numer właściciela:[[:space:]](?<owner_id>.+)$%imu,但出现了问题,因为源文本中的空格可能会在模式内部,并且这些空格必须包含在结果中,但如果有多个重复的空格,则不应包含在结果中。您尝试使用条件和负向预查来排除多个空格,但未成功。希望这有所帮助。

英文:

I'm struggling to write a proper regexp to use with PHP7.4 to extract required information from a string.

Here are the sample strings:

Numer właściciela: NOWAKOWSKA                                              01-234 Warsaw
Numer właściciela: NOWAK_S6_2
Numer właściciela: KOWALSKA_S6_                                            01-234 Warsaw
Numer właściciela: NOWACKI S6_                                             01-234 Warsaw

What I want to extract is accordingly:

NOWAKOWSKA
NOWAK_S6_2
KOWALSKA_S6_
NOWACKI S6_

So far I was using the %^Numer właściciela:[[:space:]](?<owner_id>.+)$%imu which worked fine (with example from row#2). However, turns out that the other cases (#1, #3, #4) appeared during a roll-out phase and our text extraction is not accurate enough.

The problem here is with spaces, the source text may contain space inside the pattern and this space must be included in the result. However, if there are repeating spaces, they must not be included.

Tried playing around with some conditionals and negative lookaheads to exclude multiple spaces, but failed to do so.

Would really appreciate any help here.

答案1

得分: 1

在一般情况下,当您想要匹配由单个空格分隔的字符序列时,您可以使用以下正则表达式:

/^Numer właściciela:\h*(?<owner_id>\S+(?:\h\S+)*)/imu

请查看正则表达式演示。在这里,\h 优于 \s,因为您是从更长的文本中提取数据而不是独立的文本。

如果您要提取的字符串都很短,您还可以使用以下正则表达式:

/^Numer właściciela:\h*(?<owner_id>.*?)(?:\h{2}|$)/imu

这样的话,效率可能会更高,但前提是它们与问题中的字符串一样短。.*? 通常与任意长度的字符串一样昂贵。

模式详细信息

  • ^ - 行的开头(由于 m 标志)
  • Numer właściciela: - 一个字面字符串(用 \h 替换 以匹配任何水平空格)
  • \h* - 零个或多个水平空格
  • (?<owner_id>\S+(?:\h\S+)*) - "owner_id" 组:一个或多个非空格字符,后跟零个或多个单个水平空格,然后跟一个或多个非空格字符。
  • (?<owner_id>.*?)(?:\h{2}|$) - "owner_id" 组,捕获尽可能少的零个或多个非换行字符,然后是两个水平空格或行尾。
英文:

In a general case, when you want to match sequences of chars separated with a single whitespace, you can use

/^Numer właściciela:\h*(?<owner_id>\S+(?:\h\S+)*)/imu

See the regex demo. \h is preferred to \s since you are extracting data from lines in a longer text, not standalone texts.

If the strings you extract are all short, you may also use

/^Numer właściciela:\h*(?<owner_id>.*?)(?:\h{2}|$)/imu

Then, it should be even more efficient, but only if they are that short as in the question. The .*? is usually as expensive as .* in strings of arbitrary length.

Pattern details:

  • ^ - start of a line (due to m flag)
  • Numer właściciela: - a literal string (replace with \h to match any horizontal whitespace)
  • \h* - zero or more horizontal whitespaces
  • (?<owner_id>\S+(?:\h\S+)*) - Group "owner_id": one or more non-whitespace chars followed with zero or more sequences of a single horizontal whitespace followed with one or more non-whitespace chars.
  • (?<owner_id>.*?)(?:\h{2}|$) - Group "owner_id" that captures any zero or more chars other than line break chars as few as possible, and then either two horizontal whitespaces or end of a line.

答案2

得分: 1

这个正则表达式:

/^Numer właściciela:\s+(?<owner_id>.*?)(?=\s{20,}|$)/imu

在线演示

英文:

This regex:

/^Numer właściciela:\s+(?&lt;owner_id&gt;.*?)(?=\s{20,}|$)/imu

online demo

huangapple
  • 本文由 发表于 2023年2月16日 18:16:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75470778.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定