2011-02-25 77 views

回答

4

如果字符串是$_

s/\D+?$//; 

[编辑]:如果该行可能以结尾,则应使用非贪婪匹配(+?),以避免剥夺这个角色(感谢DanD指出了这一点)。这是因为$将匹配字符串末尾或紧接在字符串末尾的\n之前。

当行文字工作,它通常是一个好主意,通过调用chomp()先去掉所有尾随\n,然后做力所能及的工作是必要的,最后追加\n当行写出。这简化了处理后缀并计算了行的长度,并且非常有用,perl提供了-l选项来使单行程的过程自动化。在这种情况下,简单的s/\D+$//;可用于:

perl -lpe "s/\D+$//" <in.txt> out.txt 
+1

是否有任何删除每行结尾的换行符的可能性有了这个? \ n由\ D匹配,所以假设如果您将它放在一个经过文件中每一行的while块中,它也会删除\ n?或者我有这个错误? – Literat 2011-02-25 22:45:03

+0

@DanD:你说得很对,我会更新。在做任何事情之前,我通常会假定这条路线已经被砍掉了,但是明确的话是值得的。 – 2011-02-25 22:52:22

5

试试这个:$line =~ s/\D+\z//;

+0

我给了这个+1,但值得记住的是'\ z'匹配字符串的结尾,所以如果字符串有一个尾部的'\ n'就不会工作(这会发生,例如,如果你'从文件中读取文本行而不是'chomp')。 – 2011-02-25 22:48:42

+0

当然会!你告诉我你认为换行符是'\ d'代码点,是吗?既然它不是'\ d',那么它必须是'\ D'。 Qᴇᴅ。 – tchrist 2011-02-26 01:20:19

+0

@tchrist:真的,它会匹配和去除'\ n',但我不会称之为“工作” - 如果我们正在处理以'\ n'结尾的字符串,它们应该保持以'\ n'结尾,你不同意吗? – 2011-02-26 02:36:42

0

试试这个:

$str =~ s/(?<=\d)\D+//; 

你可能想扔\b在那里,如果有多个目标在线:

$str =~ s/(?<=\d)\D+\b//; 

如果你只有万吨至影响行的最后一场比赛,你可以使用$来代替:

$str =~ s/(?<=\d)\D+$//; 
+1

这会将'12ABC345'变成'12345'。 – 2011-02-25 21:57:38

+0

@j_random_hacker:他原来的要求并没有说这种输入是一种可能性,或者提出了处理它的规则。它是开放的解释,所以我提供了最简单的模式。不过,我已经在编辑建议将其考虑在内。请参阅编辑。 – 2011-02-25 22:02:13

+0

他没有说它*也不是*的可能性。你不能假设非数字永远不会出现在一行的中间,仅仅因为他们没有在他的一个例子中。此外,不知道你为什么建议'\ b' - 也许有线上的其他项目,他不希望尾随非数字剥离。另外,在OP的帖子中“最后一个数字字符后面”意味着至少有一个数字,所以'(?<\ d)'是不必要的。 – 2011-02-25 22:11:17

-1

s/[A-Za-z]{2}$//;

或者,如果你想要一个一行,在DOS提示符下键入在:

perl -pe "s/[A-Za-z]{2}$//" <a.txt >b.txt

这从在每A.TXT行的末尾去除2个字母字符和保存新的数据到b.txt

如果线路没有按以2个字母字符结尾,那么该行不会被修改。如果b.txt不存在,则创建它。如果b.txt存在,则b.txt中的任何旧内容都将被销毁。 a.txt和b.txt需要位于您键入单行内容时所处的目录中,例如如果您在C:\用户中输入单行比a.txt和b.txt还需要C:\ users

+0

为什么假设后缀将是正好2个字符?他的例子仅仅是一个例子* - 他明确地说,“基本上是从右到左移除最后一个数字后面的任何字符”。为什么你认为a.txt和b.txt需要在C:\?曾听说过'cd'? – 2011-02-25 22:44:32

+0

是啊,这是真的 - 发布后我认为你的答案似乎符合OPs需求更好,因为它将是最大的。如果您将目录更改为使用cd \ users的C:\用户,那么这对于单行内容会起什么​​作用? – Literat 2011-02-25 22:49:53

+0

啊所以单行工作的任何地方 - 这很好 - 我需要改变我的帖子 – Literat 2011-02-25 22:54:44