正则表达式AND运算符?

时间:2016-08-30 00:38:17

标签: regex replace expression

我有2个字符串如下:

string str = " 2016/07/19 19:47:46]";
string str1 = " Origin (2)]";

我想让结果不是以空格开头而不是以标记结束]

"2016/07/19 19:47:46";
"Origin (2)";

我使用了模式字符串模式= @“^ [^ \ S]”,但我不知道AND运算符。

string result = Regex.Replace(str, @"^[^\S]", "");

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

BOL 的空格不在EOL标记:

(?m)^(?:\S.*|.*[^\]])$

我猜 AND 版本是:

(?m)^\S.*[^\]]$

允许0个或更多字符的另一个 AND 版本是:

(?m)^(?!\s).*(?<!\])$

答案 1 :(得分:1)

Implementations of the AND regex operator exist. The TXR language has it (notated as &) as well as the negation operator, notated ~. As you can see, though, it's not applicable to the problem. Rather, we can use it to match strings which do not start with a space and which do not end with a ]:

$ txr
This is the TXR Lisp interactive listener of TXR 147.
Use the :quit command or type Ctrl-D on empty line to exit.
1> (defun complete-match (regex string)
     (= (match-regex string regex) (length string)))
complete-match
2> (complete-match #/~ .*&~.*\]/ "")
t
3> (complete-match #/~ .*&~.*\]/ "a")
t
4> (complete-match #/~ .*&~.*\]/ "abc")
t
5> (complete-match #/~ .*&~.*\]/ " abc")
nil
6> (complete-match #/~ .*&~.*\]/ "abc]")
nil
7> (complete-match #/~ .*&~.*\]/ "]")
nil
8> (complete-match #/~ .*&~.*\]/ " ]")
nil
9> (complete-match #/~ .*&~.*\]/ " ")
nil
10> (complete-match #/~ .*&~.*\]/ "] ")
t

The complete-match function we briefly define returns t (true) or nil (false) if the input string is completely matched by the regular expression. (The automaton denoted by the regex reaches an acceptance state upon processing all the characters of the string.)

The regex is ~ .*&~.*\]. The & operator has low precedence so we can parenthesize it as (~ .*)&(~.*\]): it's an AND conjunction of two expressions. The negation operator ~ has lower precedence than catenation, so ~abc means "matches for anything other than abc": it doesn't mean [^a]bc. So ~ .* denotes the set of strings that do not begin with a space, and ~.*\] denotes the set of strings which do not end with ]. (That has to be escaped in this regex implementation, since it is a regex syntactic character).

These negated sets include empty strings. The empty string matches ~ .*, because an empty string doesn't begin with a space.

To solve the problem of trimming an optional leading space or trailing ], we can simply perform two consecutive regex replacements: delete a leading space, if any, and then delete a trailing ']', if any. The "and" logic translates to successive transformation steps: do this to input A to produce B, then do that to B to produce result C.

Regular expressions aren't required for the task, because you can simply test whether the leading character of the string is a space, and conditionally on that take either the remainder of the string or the whole string. Similarly, treat the tail:

1> (defun trim-leading-char (str ch)
      (if (equal [str 0..1] `@ch`)
        [str 1..:]
        str))
trim-leading-char
2> (defun trim-trailing-char (str ch)
      (if (equal [str -1..:] `@ch`)
        [str 0..-1]
        str))
trim-trailing-char
3> (trim-leading-char " abc]" #\space)
"abc]"
4> (trim-trailing-char " abc]" #\])
" abc"
5> (trim-trailing-char (trim-leading-char " abc]" #\space) #\])
"abc"